001/*
002 *  Copyright 2018 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.odfsync.cdmfr.actions;
017
018import java.io.InputStream;
019import java.util.HashMap;
020import java.util.HashSet;
021import java.util.Map;
022import java.util.Set;
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.acting.ServiceableAction;
028import org.apache.cocoon.environment.ObjectModelHelper;
029import org.apache.cocoon.environment.Redirector;
030import org.apache.cocoon.environment.Request;
031import org.apache.cocoon.environment.SourceResolver;
032import org.apache.cocoon.environment.http.HttpRequest;
033import org.apache.commons.collections.MapUtils;
034
035import org.ametys.cms.repository.Content;
036import org.ametys.core.cocoon.JSonReader;
037import org.ametys.core.util.AvalonLoggerAdapter;
038import org.ametys.odf.cdmfr.CDMEntity;
039import org.ametys.plugins.odfsync.cdmfr.components.ImportCDMFrComponent;
040import org.ametys.plugins.repository.AmetysObjectResolver;
041
042import com.google.common.collect.ImmutableMap;
043
044/**
045 * Import a CDM-fr file from a remote source.
046 */
047public class UploadCDMFrAction extends ServiceableAction
048{
049    /** The ametys object resolver */
050    protected AmetysObjectResolver _resolver;
051
052    /** The CDM-fr SCC component */
053    protected ImportCDMFrComponent _importCDMFrComponent;
054    
055    @Override
056    public void service(ServiceManager sManager) throws ServiceException
057    {
058        super.service(sManager);
059        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
060        _importCDMFrComponent = (ImportCDMFrComponent) manager.lookup(ImportCDMFrComponent.ROLE);
061    }
062
063    @Override
064    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
065    {
066        getLogger().info("Start of upload CDM-FR file");
067
068        Request request = ObjectModelHelper.getRequest(objectModel);
069        if (request instanceof HttpRequest)
070        {
071            try (InputStream is = ((HttpRequest) request).getInputStream())
072            {
073                Map<String, Object> resultMap = _importCDMFrComponent.handleInputStream(is, ImmutableMap.of(), new AvalonLoggerAdapter(getLogger()));
074                request.setAttribute(JSonReader.OBJECT_TO_READ, _convertForResult(resultMap));
075            }
076        }
077        
078        getLogger().info("End of upload CDM-FR file");
079        
080        return EMPTY_MAP;
081    }
082    
083    /**
084     * Convert the resultMap from the {@link ImportCDMFrComponent} to a result map to send as response.
085     * @param resultMap The result map to transform
086     * @return A {@link Map} of results as response
087     */
088    @SuppressWarnings("unchecked")
089    protected Map<String, Object> _convertForResult(Map<String, Object> resultMap)
090    {
091        Map<String, Object> result = new HashMap<>();
092
093        result.put("nbCreatedContents", resultMap.get("nbCreatedContents"));
094        result.put("nbSynchronizedContents", resultMap.get("nbSynchronizedContents"));
095        result.put("nbNotChangedContents", resultMap.get("nbNotChangedContents"));
096        result.put("nbError", resultMap.get("nbError"));
097        
098        result.put("importedContents", _groupByContentType(((Map<String, Object>) resultMap.getOrDefault("importedContents", MapUtils.EMPTY_MAP)).keySet()));
099        result.put("synchronizedContents", _groupByContentType((Set<String>) resultMap.get("synchronizedContents")));
100        result.put("updatedContents", _groupByContentType((Set<String>) resultMap.get("updatedContents")));
101
102        return result;
103    }
104    
105    private Map<String, Set<String>> _groupByContentType(Set<String> contentIds)
106    {
107        Map<String, Set<String>> contentTitlesByContentType = new HashMap<>();
108        
109        if (contentIds != null)
110        {
111            for (String contentId : contentIds)
112            {
113                Content content = _resolver.resolveById(contentId);
114                if (content instanceof CDMEntity)
115                {
116                    String contentTitle = content.getTitle() + " (" + ((CDMEntity) content).getCdmCode() + ")";
117                    for (String contentType : content.getTypes())
118                    {
119                        Set<String> contents = contentTitlesByContentType.get(contentType);
120                        if (contents == null)
121                        {
122                            contents = new HashSet<>();
123                        }
124                        if (contents.add(contentTitle))
125                        {
126                            contentTitlesByContentType.put(contentType, contents);
127                        }
128                    }
129                }
130            }
131        }
132        
133        return contentTitlesByContentType;
134    }
135}