001/*
002 *  Copyright 2024 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.plugins.explorer.resources;
018
019import java.util.ArrayList;
020import java.util.HashMap;
021import java.util.List;
022import java.util.Map;
023
024import org.apache.avalon.framework.component.Component;
025import org.apache.avalon.framework.context.Context;
026import org.apache.avalon.framework.context.ContextException;
027import org.apache.avalon.framework.context.Contextualizable;
028import org.apache.avalon.framework.service.ServiceException;
029import org.apache.avalon.framework.service.ServiceManager;
030import org.apache.avalon.framework.service.Serviceable;
031import org.apache.cocoon.components.ContextHelper;
032import org.apache.cocoon.environment.Request;
033import org.apache.cocoon.servlet.multipart.Part;
034
035import org.ametys.core.cocoon.JSonReader;
036import org.ametys.core.ui.Callable;
037import org.ametys.plugins.explorer.resources.actions.AddOrUpdateResourceHelper;
038import org.ametys.plugins.explorer.resources.actions.AddOrUpdateResourceHelper.ResourceOperationMode;
039import org.ametys.plugins.explorer.resources.actions.AddOrUpdateResourceHelper.ResourceOperationResult;
040import org.ametys.plugins.repository.RepositoryConstants;
041import org.ametys.plugins.repository.provider.RequestAttributeWorkspaceSelector;
042
043/**
044 * Adding or updating a resource file.
045 */
046public class AddOrUpdateResource implements Serviceable, Contextualizable, Component
047{
048    /** Avalon Role */
049    public static final String ROLE = AddOrUpdateResource.class.getName();
050    
051    /** resource operation helper */
052    protected AddOrUpdateResourceHelper _addOrUpdateResourceHelper;
053    
054    /** The avalon context */
055    protected Context _context;
056    
057    @Override
058    public void service(ServiceManager serviceManager) throws ServiceException
059    {
060        _addOrUpdateResourceHelper = (AddOrUpdateResourceHelper) serviceManager.lookup(AddOrUpdateResourceHelper.ROLE);
061    }
062    
063    @Override
064    public void contextualize(Context context) throws ContextException
065    {
066        _context = context;
067    }
068    
069    /**
070     * Add, add and rename or update a resource
071     * @param parentId The id of the collection parent
072     * @param rawMode The mode
073     * @param unzip If there is an unzip to be done 
074     * @param parts The parts to import
075     * @return The results
076     */
077    @SuppressWarnings("unchecked")
078    @Callable (rights = "Plugin_Explorer_File_Add", paramIndex = 0, rightContext = "right.assignment.context.resource")
079    public Map addOrUpdateResources(String parentId, String rawMode, Boolean unzip, List<Part> parts)
080    {
081        Request request = ContextHelper.getRequest(_context);
082        
083        // Retrieve the current workspace.
084        String currentWsp = RequestAttributeWorkspaceSelector.getForcedWorkspace(request);
085        
086        try
087        {
088            // Force the default workspace.
089            RequestAttributeWorkspaceSelector.setForcedWorkspace(request, RepositoryConstants.DEFAULT_WORKSPACE);
090            
091            Map<String, Object> result = new HashMap<>();
092            List<Map<String, Object>> resultsForFileSuccess = new ArrayList<>();
093            
094            for (Part part : parts)
095            {
096                Map<String, Object> resultForPart = new HashMap<>();
097                String rawModeForPart = rawMode;
098                
099                if (unzip && part.getFileName().endsWith(".zip"))
100                {
101                    rawModeForPart = "add-unzip";
102                }
103                
104                ResourceOperationMode mode = ResourceOperationMode.createsFromRawMode(rawModeForPart);
105                
106                // perform the add/update operation
107                _addOrUpdateResourceHelper.checkAddResourceRight(parentId);
108                ResourceOperationResult operationResult = _addOrUpdateResourceHelper.performResourceOperation(part, parentId, mode);
109                
110                if (!operationResult.isSuccess())
111                {
112                    Map<String, String> errors = (Map<String, String>) result.computeIfAbsent("message", l -> new HashMap<>());
113                    errors.put(part.getFileName(), operationResult.getErrorMessage());
114                }
115                else
116                {
117                    result.put("parentID", parentId);
118                    result.put("success", true);
119                    
120                    if (operationResult.isUnzip())
121                    {
122                        resultForPart.put("unzip", true);
123                        resultForPart.put("reload", true);
124                    }
125                    else
126                    {
127                        Resource resource = operationResult.getResource();
128                        resultForPart.put("id", resource.getId());
129                        resultForPart.put("name", resource.getName());
130                    }
131                    resultsForFileSuccess.add(resultForPart);
132                }
133            }
134            
135            result.put("resultsForFileSuccess", resultsForFileSuccess);
136            
137            request.setAttribute(JSonReader.OBJECT_TO_READ, result);
138            return result;
139        }
140        finally
141        {
142            // Restore context
143            RequestAttributeWorkspaceSelector.setForcedWorkspace(request, currentWsp);
144        }
145    }
146}