001/*
002 *  Copyright 2014 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.contentio.in;
017
018import java.io.ByteArrayOutputStream;
019import java.io.File;
020import java.io.IOException;
021import java.io.PrintStream;
022import java.nio.charset.StandardCharsets;
023import java.util.HashMap;
024import java.util.Map;
025import java.util.Set;
026
027import org.apache.avalon.framework.parameters.Parameters;
028import org.apache.avalon.framework.service.ServiceException;
029import org.apache.avalon.framework.service.ServiceManager;
030import org.apache.cocoon.acting.ServiceableAction;
031import org.apache.cocoon.environment.ObjectModelHelper;
032import org.apache.cocoon.environment.Redirector;
033import org.apache.cocoon.environment.Request;
034import org.apache.cocoon.environment.SourceResolver;
035import org.apache.cocoon.servlet.multipart.Part;
036import org.apache.cocoon.servlet.multipart.PartOnDisk;
037import org.apache.cocoon.servlet.multipart.RejectedPart;
038import org.apache.commons.io.IOUtils;
039import org.apache.commons.lang.StringUtils;
040import org.apache.excalibur.source.Source;
041
042import org.ametys.core.util.I18nUtils;
043import org.ametys.core.util.mail.SendMailHelper;
044import org.ametys.plugins.contentio.in.ContentImportManager.ImportResult;
045import org.ametys.runtime.config.Config;
046import org.ametys.runtime.i18n.I18nizableText;
047
048import jakarta.mail.MessagingException;
049
050/**
051 * Import contents from an uploaded file.
052 */
053public class ImportFileAction extends ServiceableAction
054{
055    
056    /** The content import manager. */
057    protected ContentImportManager _importManager;
058    
059    /** The source resolver. */
060    protected org.apache.excalibur.source.SourceResolver _sourceResolver;
061    
062    /** The i18n utils. */
063    protected I18nUtils _i18nUtils;
064    
065    @Override
066    public void service(ServiceManager serviceManager) throws ServiceException
067    {
068        super.service(serviceManager);
069        _importManager = (ContentImportManager) serviceManager.lookup(ContentImportManager.ROLE);
070        _sourceResolver = (org.apache.excalibur.source.SourceResolver) serviceManager.lookup(org.apache.excalibur.source.SourceResolver.ROLE);
071        _i18nUtils = (I18nUtils) serviceManager.lookup(I18nUtils.ROLE);
072    }
073    
074    @Override
075    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
076    {
077        Request request = ObjectModelHelper.getRequest(objectModel);
078        
079        boolean sendMail = parameters.getParameterAsBoolean("send-mail", false);
080        
081        boolean success = false;
082        
083        Map<String, String> result = new HashMap<>();
084        
085        ImportResult importResult = null;
086        
087        Part part = (Part) request.get("file");
088        if (part instanceof RejectedPart || part == null)
089        {
090            result.put("error", "rejected");
091        }
092        else
093        {
094            PartOnDisk uploadedFilePart = (PartOnDisk) part;
095            File uploadedFile = uploadedFilePart.getFile();
096            
097            try
098            {
099                importResult = _importManager.importContents(uploadedFile);
100                
101                if (!importResult.isImporterFound())
102                {
103                    result.put("error", "no-importer");
104                }
105                else
106                {
107                    Set<String> contentIds = importResult.getImportedContentIds();
108                    success = true;
109                    
110                    result.put("importedCount", Integer.toString(contentIds.size()));
111                    result.put("importedIds", StringUtils.join(contentIds, '|'));
112                }
113            }
114            catch (ContentImportException e)
115            {
116                ByteArrayOutputStream os = new ByteArrayOutputStream();
117                e.printStackTrace(new PrintStream(os));
118                getLogger().error("Exception importing contents from file: " + uploadedFile.getName(), e);
119                result.put("message", os.toString());
120            }
121        }
122        
123        result.put("success", String.valueOf(success));
124        
125        if (sendMail)
126        {
127            sendMail(success, importResult);
128        }
129        
130        return result;
131    }
132    
133    /**
134     * Send an import report as e-mail.
135     * @param success true if the import was successful, false otherwise.
136     * @param importResult the import result.
137     */
138    protected void sendMail(boolean success, ImportResult importResult)
139    {
140        try
141        {
142            String sysadminMail = Config.getInstance().getValue("smtp.mail.sysadminto");
143            String baseUrl = StringUtils.stripEnd(StringUtils.removeEndIgnoreCase(Config.getInstance().getValue("cms.url"), "index.html"), "/");
144            
145            Map<String, Object> mailParams = new HashMap<>();
146            
147            if (success)
148            {
149                mailParams.put("success", true);
150                mailParams.put("baseUrl", baseUrl);
151                mailParams.put("contentIds", importResult.getImportedContentIds());
152            }
153            else
154            {
155                mailParams.put("success", false);
156                if (importResult != null && !importResult.isImporterFound())
157                {
158                    mailParams.put("error", "no-importer");
159                }
160            }
161            
162            Source bodySource = _sourceResolver.resolveURI("cocoon://_plugins/contentio/mail/body", null, mailParams);
163            String body = IOUtils.toString(bodySource.getInputStream(), StandardCharsets.UTF_8);
164            
165            I18nizableText i18nSubject = new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_IMPORTFILE_MAIL_SUBJECT");
166            String subject = _i18nUtils.translate(i18nSubject);
167            
168            if (StringUtils.isNotBlank(sysadminMail))
169            {
170                SendMailHelper.newMail()
171                              .withSubject(subject)
172                              .withTextBody(body)
173                              .withRecipient(sysadminMail)
174                              .sendMail();
175            }
176        }
177        catch (MessagingException | IOException e)
178        {
179            getLogger().warn("Error sending the import report e-mail.", e);
180        }
181    }
182    
183}