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 */
016
017package org.ametys.web.repository.dom;
018
019import java.util.Iterator;
020
021import org.w3c.dom.Element;
022import org.w3c.dom.Node;
023
024import org.ametys.core.right.RightManager;
025import org.ametys.core.user.UserIdentity;
026import org.ametys.plugins.repository.AmetysObjectIterable;
027import org.ametys.plugins.repository.dom.AmetysObjectElement;
028import org.ametys.web.pageaccess.RestrictedPagePolicy;
029import org.ametys.web.renderingcontext.RenderingContext;
030import org.ametys.web.renderingcontext.RenderingContextHandler;
031import org.ametys.web.repository.page.Page;
032import org.ametys.web.repository.page.PagesContainer;
033
034/**
035 * DOM {@link Element} wrapping a {@link PagesContainer}.
036 * @param <A> the actual type of the wrapped {@link PagesContainer}.
037 */
038public abstract class AbstractPagesContainerElement<A extends PagesContainer> extends AmetysObjectElement<A>
039{
040    /** Prefix for sitemap namespace. */
041    public static final String NAMESPACE_PREFIX = "sitemap";
042    /** URI for sitemap namespace. */
043    public static final String NAMESPACE_URI = "http://www.ametys.org/inputdata/sitemap/3.0";
044
045    /** The right manager */
046    protected RightManager _rightManager;
047    /** The rendering context handler. */
048    protected RenderingContextHandler _renderingContextHandler;
049    /** The path of the wrapped page. */
050    protected String _currentPagePath;
051    /** The identity of the current user. */
052    protected UserIdentity _userIdentity;
053    /** the {@link RestrictedPagePolicy} of the current site. */
054    protected RestrictedPagePolicy _policy;
055    /** should child pages displays invisible page */
056    protected boolean _includeInvisiblePages;
057    
058    private AmetysObjectIterable<? extends Page> _children;
059    
060    /**
061     * Constructor.
062     * @param pagesContainer the wrapped {@link PagesContainer}.
063     * @param rightManager the right manager
064     * @param currentPagePath the path of the current page, or null if none.
065     * @param renderingContextHandler the {@link RenderingContextHandler}.
066     * @param userIdentity the identity of the current user, or null if none.
067     * @param includeInvisiblePages Should return child invisible pages
068     */
069    public AbstractPagesContainerElement(A pagesContainer, RightManager rightManager, RenderingContextHandler renderingContextHandler, String currentPagePath, UserIdentity userIdentity, boolean includeInvisiblePages)
070    {
071        this(pagesContainer, null, rightManager, renderingContextHandler, currentPagePath, userIdentity, includeInvisiblePages);
072    }
073    
074    /**
075     * Constructor.
076     * @param pagesContainer the wrapped {@link PagesContainer}.
077     * @param parent the parent container.
078     * @param rightManager the right manager
079     * @param currentPagePath the path of the current page, or null if none.
080     * @param renderingContextHandler the {@link RenderingContextHandler}.
081     * @param userIdentity the identity of the current user, or null if none.
082     * @param includeInvisiblePages Should return child invisible pages
083     */
084    public AbstractPagesContainerElement(A pagesContainer, AbstractPagesContainerElement<PagesContainer> parent, RightManager rightManager, RenderingContextHandler renderingContextHandler, String currentPagePath, UserIdentity userIdentity, boolean includeInvisiblePages)
085    {
086        super(pagesContainer, parent);
087        _rightManager = rightManager;
088        _renderingContextHandler = renderingContextHandler;
089        _currentPagePath = currentPagePath;
090        _userIdentity = userIdentity;
091        _policy = _object.getSite().getRestrictedPagePolicy();
092        _includeInvisiblePages = includeInvisiblePages;
093    }
094    
095    @Override
096    public String getNamespaceURI()
097    {
098        //return "http://www.ametys.org/inputdata/sitemap/3.0";
099        return null;
100    }
101    
102    AmetysObjectIterable<? extends Page> getChildren()
103    {
104        if (_children == null)
105        {
106            _children = _object.getChildrenPages(_includeInvisiblePages);
107        }
108        
109        return _children;
110    }
111    
112    @Override
113    public boolean hasChildNodes()
114    {
115        if (_children == null)
116        {
117            _children = _object.getChildrenPages(_includeInvisiblePages);
118        }
119        
120        return _children.iterator().hasNext();
121    }
122    
123    @SuppressWarnings("unchecked")
124    @Override
125    public Node getFirstChild()
126    {
127        if (_children == null)
128        {
129            _children = _object.getChildrenPages(_includeInvisiblePages);
130        }
131        
132        Iterator<? extends Page> it = _children.iterator();
133        
134        if (!it.hasNext())
135        {
136            return null;
137        }
138        
139        RenderingContext renderingContext = _renderingContextHandler.getRenderingContext();
140        boolean inBackOffice = renderingContext == RenderingContext.BACK || renderingContext == RenderingContext.PREVIEW;
141        
142        Page child = null;
143        
144        while (child == null && it.hasNext())
145        {
146            Page page = it.next();
147            if (inBackOffice || _policy == RestrictedPagePolicy.DISPLAYED || _rightManager.hasReadAccess(_userIdentity, page))
148            {
149                child = page;
150            }
151        }
152        
153        return child == null ? null : new PageElement(child, (AbstractPagesContainerElement<PagesContainer>) this, _rightManager, _renderingContextHandler, _currentPagePath, _userIdentity, _includeInvisiblePages);
154    }
155    
156    @SuppressWarnings("unchecked")
157    @Override
158    public Node getNextSibling()
159    {
160        if (_parent == null)
161        {
162            return null;
163        }
164        
165        AmetysObjectIterable<? extends Page> children = ((AbstractPagesContainerElement<PagesContainer>) _parent).getChildren();
166        
167        RenderingContext renderingContext = _renderingContextHandler.getRenderingContext();
168        boolean inBackOffice = renderingContext == RenderingContext.BACK || renderingContext == RenderingContext.PREVIEW;
169        
170        boolean isNext = false;
171        Page nextSibling = null;
172        Iterator<? extends Page> it = children.iterator();
173        
174        while (nextSibling == null && it.hasNext())
175        {
176            Page child = it.next();
177            
178            if (isNext && (inBackOffice || _policy == RestrictedPagePolicy.DISPLAYED || _rightManager.hasReadAccess(_userIdentity, child)))
179            {
180                nextSibling = child;
181            }
182            else if (_object.getId().equals(child.getId()))
183            {
184                isNext = true;
185            }
186        }
187        
188        return nextSibling == null ? null : new PageElement(nextSibling, (AbstractPagesContainerElement<PagesContainer>) _parent, _rightManager, _renderingContextHandler, _currentPagePath, _userIdentity, _includeInvisiblePages);
189    }
190}