001/*
002 *  Copyright 2015 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.explorer;
017
018import java.util.ArrayList;
019import java.util.List;
020import java.util.Map;
021import java.util.Set;
022import java.util.regex.Pattern;
023
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.cocoon.components.ContextHelper;
027import org.apache.cocoon.environment.Request;
028import org.apache.commons.lang.StringUtils;
029
030import org.ametys.plugins.explorer.ExplorerNode;
031import org.ametys.plugins.explorer.resources.Resource;
032import org.ametys.plugins.repository.AmetysObject;
033import org.ametys.runtime.config.Config;
034import org.ametys.runtime.i18n.I18nizableText;
035import org.ametys.web.repository.page.Page;
036import org.ametys.web.repository.site.SiteManager;
037
038
039/**
040 * This DAO overrides {@link org.ametys.cms.explorer.ExplorerResourcesDAO} to handle shared explorer resources and page attachments.
041 */
042public class ExplorerResourcesDAO extends org.ametys.cms.explorer.ExplorerResourcesDAO
043{
044    /** site explorer resource pattern */
045    private static final Pattern __RESOURCE_PATTERN = Pattern.compile("^.*/" + SiteManager.ROOT_SITES + "/([^/]+)/ametys-internal:resources(/.*)?$");
046    /** shared explorer resource pattern */
047    private static final Pattern __SHARED_RESOURCE_PATTERN = Pattern.compile("^.*" + ResourceHelper.SHARED_RESOURCE_PATH + "(/.*)?$");
048
049    /** Site manager */
050    protected SiteManager _siteManager;
051    
052    @Override
053    public void service(ServiceManager manager) throws ServiceException
054    {
055        super.service(manager);
056        _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE);
057    }
058    
059    @Override
060    public List<ExplorerNode> getResourcesRootNodes()
061    {
062        Request request = ContextHelper.getRequest(_context);
063        String siteName = (String) request.getAttribute("siteName");
064        
065        List<ExplorerNode> rootNodes = new ArrayList<>();
066        
067        // Site root
068        if (StringUtils.isNotEmpty(siteName))
069        {
070            AmetysObject resourcesRootAO = _siteManager.getSite(siteName).getRootResources();
071            if (resourcesRootAO instanceof ExplorerNode)
072            {
073                rootNodes.add((ExplorerNode) resourcesRootAO);
074            }
075        }
076        
077        // Shared root
078        boolean useShared = Config.getInstance().getValue("resources.shared.folder");
079        if (useShared)
080        {
081            ExplorerNode sharedRoot = _resolver.resolveByPath(ResourceHelper.SHARED_RESOURCE_PATH + "/all");
082            rootNodes.add(sharedRoot);
083        }
084        
085        return rootNodes;
086    }
087    
088    @Override
089    public Map<String, Object> getDefaultInfoAsRootNode(ExplorerNode rootNode)
090    {
091        if (rootNode.getPath().startsWith(ResourceHelper.SHARED_RESOURCE_PATH))
092        {
093            return getSharedRootNodeInfo(rootNode);
094        }
095        return super.getDefaultInfoAsRootNode(rootNode);
096    }
097    
098    /**
099     * Get the necessary info for the shared root node.
100     * Can be used to construct a root node for a tree (client side).
101     * @param sharedRoot The shared root node
102     * @return A map which contains a set of default info (such as id, applicationId, path, type etc...)
103     */
104    public Map<String, Object> getSharedRootNodeInfo(ExplorerNode sharedRoot)
105    {
106        Map<String, Object> result = super.getDefaultInfoAsRootNode(sharedRoot);
107        
108        String name = "shared-resources-" + sharedRoot.getName();
109        result.put("name", name);
110        result.put("cls", "shared-root");
111        result.put("iconCls", "ametysicon-folder249 decorator-ametysicon-world91");
112        result.put("text", _getSharedRootNodeLabel());
113        result.put("path", "/dummy/" + name);
114        result.put("isShared", true);
115        return result;
116    }
117    
118    @Override
119    public I18nizableText getRootNodeLabel(ExplorerNode rootNode)
120    {
121        if (rootNode.getPath().startsWith(ResourceHelper.SHARED_RESOURCE_PATH))
122        {
123            return _getSharedRootNodeLabel();
124        }
125        return super.getRootNodeLabel(rootNode);
126    }
127
128    private I18nizableText _getSharedRootNodeLabel()
129    {
130        return new I18nizableText("plugin.web", "PLUGINS_WEB_EXPLORER_SHARED");
131    }
132    
133    @Override
134    public Map<String, Object> getResourceProperties(Resource resource)
135    {
136        Map<String, Object> infos = super.getResourceProperties(resource);
137        
138        boolean isShared = ResourceHelper.isShared(resource);
139        infos.put("isShared", isShared);
140
141        if (isShared)
142        {
143            String sharedRoot = ResourceHelper.getSharedRootName(resource);
144            infos.put("sharedRoot", sharedRoot);
145        }
146        
147        if (_getParentPage(resource) != null)
148        {
149            infos.put("rootOwnerType", "page");
150        }
151        
152        return infos;
153    }
154    
155    @Override
156    public Set<Pattern> getExplorerNodePathPatterns()
157    {
158        return Set.of(__RESOURCE_PATTERN, __SHARED_RESOURCE_PATTERN);
159    }
160    
161    @Override
162    public Map<String, Object> getExplorerNodeProperties(ExplorerNode node)
163    {
164        Map<String, Object> infos = super.getExplorerNodeProperties(node);
165        
166        boolean isShared = ResourceHelper.isShared(node);
167        infos.put("isShared", isShared);
168        
169        if (isShared)
170        {
171            String sharedRoot = ResourceHelper.getSharedRootName(node);
172            infos.put("sharedRoot", sharedRoot);
173        }
174        
175        if (_getParentPage(node) != null)
176        {
177            infos.put("rootOwnerType", "page");
178        }
179        
180        return infos;
181    }
182    
183    @Override
184    protected Set<String> getUserRights(ExplorerNode node)
185    {
186        Page parentPage = _getParentPage(node);
187        if (parentPage != null)
188        {
189            return _rightManager.getUserRights(_currentUserProvider.getUser(), parentPage);
190        }
191        
192        return super.getUserRights(node);
193    }
194    
195    /**
196     * Get the parent page of a resource or collection
197     * @param ao The resource or collection
198     * @return the parent page or null if the object is not part of page attachments
199     */
200    protected Page _getParentPage (AmetysObject ao)
201    {
202        AmetysObject parent = ao.getParent();
203        while (parent != null)
204        {
205            if (parent instanceof Page)
206            {
207                return (Page) parent;
208            }
209            parent = parent.getParent();
210        }
211        return null;
212    }
213}