001/*
002 *  Copyright 2016 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.cms.fo;
017
018import java.util.Enumeration;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022import java.util.Map.Entry;
023
024import org.apache.cocoon.environment.ObjectModelHelper;
025import org.apache.cocoon.environment.Request;
026import org.apache.commons.lang3.StringUtils;
027import org.xml.sax.SAXException;
028
029import org.ametys.core.ui.dispatcher.DispatchGenerator;
030import org.ametys.plugins.repository.provider.RequestAttributeWorkspaceSelector;
031
032/**
033 * The purpose of this action is to handle front office requests.
034 * These requests are usually AJAX requests coming from services.
035 * The processing is loosely based on the {@link DispatchGenerator}
036 */
037public class FODispatchGenerator extends DispatchGenerator
038{
039    @Override
040    protected void _dispatching(Map<String, Object> requestBody, Map<String, Object> contextAsMap) throws SAXException
041    {
042        contentHandler.startDocument();
043        
044        Map<String, Object> attributes = _requestAttributesHelper.saveRequestAttributes();
045        contextAsMap.putAll(transmitAttributes(attributes));
046        
047        Request request = ObjectModelHelper.getRequest(objectModel);
048        String currentWorkspace = RequestAttributeWorkspaceSelector.getForcedWorkspace(request);
049        
050        try
051        {
052            RequestAttributeWorkspaceSelector.setForcedWorkspace(request, "default");
053            // Handle one sub request from FO
054            _dispatchingSubRequest(requestBody, contextAsMap, "0");
055        }
056        finally 
057        {
058            RequestAttributeWorkspaceSelector.setForcedWorkspace(request, currentWorkspace);
059        }
060        
061        _requestAttributesHelper.restoreRequestAttributes(attributes);
062        
063        contentHandler.endDocument();
064    }
065    
066    @Override
067    protected void _removeRequestAttributes()
068    {
069        // WORKSPACES-147 Possible WorkspacesFoRequestGenerator request attributes
070        // FIXME Cannot remove request attributes, because necessary FO attributes like Web:FrontOffice:UserIdentity will be removed.
071    }
072    
073    @Override
074    protected void _handleFiles (Map<String, Object> requestParameters, String parameterKey)
075    {
076        Map<String, Object> uploadedFiles = _extractFiles();
077        
078        if (requestParameters != null && !uploadedFiles.isEmpty())
079        {
080            @SuppressWarnings("unchecked")
081            List<Object> callableParameters = (List) requestParameters.get("parameters");
082            
083            if (callableParameters != null)
084            {
085                // Replace file parameters by real files
086                for (Entry<String, Object> entry : uploadedFiles.entrySet())
087                {
088                    String fileIndex = StringUtils.substringAfter(entry.getKey(), "file-");
089                    if (fileIndex.contains("-"))
090                    {
091                        int parameterIndex = Integer.parseInt(StringUtils.substringBefore(fileIndex, "-"));
092                        int arrayIndex = Integer.parseInt(StringUtils.substringAfter(fileIndex, "-"));
093                        @SuppressWarnings("unchecked")
094                        List<Object> params = (List<Object>) callableParameters.get(parameterIndex);
095                        params.remove(arrayIndex);
096                        params.add(arrayIndex, entry.getValue());
097                    }
098                    else
099                    {
100                        int parameterIndex = Integer.parseInt(fileIndex);
101                        
102                        callableParameters.remove(parameterIndex);
103                        callableParameters.add(parameterIndex, entry.getValue());
104                    }
105                }
106            }
107        }
108    }
109    
110    private Map<String, Object> _extractFiles()
111    {
112        Request request = ObjectModelHelper.getRequest(objectModel);
113        
114        Map<String, Object> files = new HashMap<>();
115        
116        // Extract the optional list of uploaded files
117        Enumeration paramNames = request.getParameterNames();
118        while (paramNames.hasMoreElements())
119        {
120            String paramName = (String) paramNames.nextElement();
121            if (paramName.startsWith("file-"))
122            {
123                files.put(paramName, request.get(paramName));
124            }
125        }
126        
127        return files;
128    }
129}