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