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