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}