001/*
002 *  Copyright 2017 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.extraction.execution;
017
018import java.util.ArrayList;
019import java.util.Collection;
020import java.util.HashMap;
021import java.util.List;
022import java.util.Map;
023
024import org.apache.avalon.framework.parameters.Parameters;
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.cocoon.environment.ObjectModelHelper;
028import org.apache.cocoon.environment.Redirector;
029import org.apache.cocoon.environment.Request;
030import org.apache.cocoon.environment.SourceResolver;
031import org.apache.commons.lang3.StringUtils;
032import org.apache.excalibur.source.TraversableSource;
033import org.apache.excalibur.source.impl.FileSource;
034
035import org.ametys.core.cocoon.JSonReader;
036import org.ametys.core.group.GroupManager;
037import org.ametys.core.right.RightManager;
038import org.ametys.core.right.RightManager.RightResult;
039import org.ametys.core.user.CurrentUserProvider;
040import org.ametys.core.user.UserIdentity;
041import org.ametys.plugins.core.ui.parameter.files.GetParameterFileAction;
042import org.ametys.plugins.core.user.UserHelper;
043import org.ametys.plugins.extraction.ExtractionConstants;
044
045/**
046 * Action for getting extraction definition files
047 */
048public class GetExtractionDefinitionFilesAction extends GetParameterFileAction
049{
050    private RightManager _rightManager;
051    private CurrentUserProvider _currentUserProvider;
052    private ExtractionDefinitionReader _definitionReader;
053    private UserHelper _userHelper;
054    private GroupManager _groupManager;
055    
056    @Override
057    public void service(ServiceManager serviceManager) throws ServiceException
058    {
059        super.service(serviceManager);
060        _rightManager = (RightManager) serviceManager.lookup(RightManager.ROLE);
061        _currentUserProvider = (CurrentUserProvider) serviceManager.lookup(CurrentUserProvider.ROLE);
062        _definitionReader = (ExtractionDefinitionReader) serviceManager.lookup(ExtractionDefinitionReader.ROLE);
063        _userHelper = (UserHelper) serviceManager.lookup(UserHelper.ROLE);
064        _groupManager = (GroupManager) serviceManager.lookup(GroupManager.ROLE);
065    }
066    
067    @Override
068    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
069    {
070        if (_rightManager.hasRight(_currentUserProvider.getUser(), ExtractionConstants.EXECUTE_EXTRACTION_RIGHT_ID, "/${WorkspaceName}") != RightResult.RIGHT_ALLOW)
071        {
072            String errorMessage = "User " + _currentUserProvider.getUser() + " try to list extraction definition files with no sufficient rights"; 
073            getLogger().error(errorMessage);
074            throw new IllegalStateException(errorMessage);
075        }
076        
077        Request request = ObjectModelHelper.getRequest(objectModel);
078        
079        String path = StringUtils.defaultString(request.getParameter("path"), "");
080        
081        String rootURI = getRootURI(request);
082        TraversableSource rootDir = (TraversableSource) _srcResolver.resolveURI(rootURI);
083        TraversableSource currentDir = (TraversableSource) _srcResolver.resolveURI(rootURI + (path.length() > 0 ? "/" + path : ""));
084        
085        List<Map<String, Object>> nodes = new ArrayList<>();
086        
087        if (currentDir.exists())
088        {
089            for (TraversableSource child : (Collection<TraversableSource>) currentDir.getChildren())
090            {
091                if (!isIgnoredSource(child))
092                {
093                    if (child.isCollection())
094                    {
095                        nodes.add(_collection2JsonObject(child, rootDir));
096                    }
097                    else
098                    {
099                        // To parse the extraction definition file only once, check here if the current user can read it
100                        Extraction extraction = _definitionReader.readExtractionDefinitionFile(((FileSource) child).getFile());
101                        if (extraction.canRead(_currentUserProvider.getUser(), _groupManager))
102                        {
103                            nodes.add(_extraction2JsonObject(extraction, child, rootDir));
104                        }
105                    }
106                }
107            }
108        }
109        
110        Map<String, Object> result = new HashMap<>();
111        result.put("nodes", nodes);
112        
113        request.setAttribute(JSonReader.OBJECT_TO_READ, result);
114        return EMPTY_MAP;
115    }
116        
117    @Override
118    protected String getRootURI(Request request)
119    {
120        return ExtractionConstants.DEFINITIONS_DIR;
121    }
122        
123    @Override
124    protected boolean isIgnoredSource(TraversableSource source)
125    {
126        return !source.isCollection() && !source.getName().endsWith(".xml");
127    }
128    
129    private Map<String, Object> _extraction2JsonObject(Extraction extraction, TraversableSource file, TraversableSource root)
130    {
131        Map<String, Object> jsonObject = super._resource2JsonObject(file, root);
132        
133        jsonObject.put("descriptionId", extraction.getDescriptionId());
134        jsonObject.put("visibility", extraction.getVisibility().toString());
135        jsonObject.put("author", _userHelper.user2json(extraction.getAuthor()));
136
137        UserIdentity currentUser = _currentUserProvider.getUser();
138        jsonObject.put("canRead", extraction.canRead(currentUser, _groupManager));
139        jsonObject.put("canWrite", extraction.canWrite(currentUser, _groupManager));
140        
141        return jsonObject;
142    }
143}