package org.sigmah.server.handler; /* * #%L * Sigmah * %% * Copyright (C) 2010 - 2016 URD * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import com.google.inject.Inject; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.sigmah.server.dispatch.impl.UserDispatch; import org.sigmah.server.handler.base.AbstractCommandHandler; import org.sigmah.server.i18n.I18nServer; import org.sigmah.server.mail.ModelMailService; import org.sigmah.shared.Language; import org.sigmah.shared.command.PrepareFileUpload; import org.sigmah.shared.command.Synchronize; import org.sigmah.shared.command.UpdateProject; import org.sigmah.shared.command.base.Command; import org.sigmah.shared.command.result.Result; import org.sigmah.shared.command.result.SynchronizeResult; import org.sigmah.shared.dispatch.CommandException; import org.sigmah.shared.dispatch.UpdateConflictException; import org.sigmah.shared.dto.referential.ContainerInformation; import org.sigmah.shared.dto.referential.EmailKey; import org.sigmah.shared.dto.referential.EmailKeyEnum; import org.sigmah.shared.dto.referential.EmailType; import org.sigmah.shared.dto.value.FileUploadUtils; import org.sigmah.shared.dto.value.FileVersionDTO; /** * Handler for {@link Synchronize} command. * * @author Raphaƫl Calabro (rcalabro@ideia.fr) */ public class SynchronizeHandler extends AbstractCommandHandler<Synchronize, SynchronizeResult> { /** * Access to the localized strings. */ @Inject private I18nServer i18nServer; /** * Service to send emails. */ @Inject private ModelMailService modelMailService; /** * {@inheritDoc} */ @Override protected SynchronizeResult execute(Synchronize synchronize, UserDispatch.UserExecutionContext context) throws CommandException { final HashMap<ContainerInformation, List<String>> errors = new HashMap<>(); final HashMap<Integer, Integer> files = new HashMap<>(); boolean errorConcernFiles = false; for (final Command<?> command : synchronize.getCommands()) { try { if (command instanceof UpdateProject) { ((UpdateProject)command).setComment(i18nServer.t(context.getLanguage(), "sigmahOfflineSynchronizeUpdateComment")); } final Result result = context.execute(command); if (command instanceof PrepareFileUpload) { final String negativeId = ((PrepareFileUpload)command).getProperties().get(FileUploadUtils.GENERATED_ID); final FileVersionDTO fileVersion = (FileVersionDTO)result; files.put(Integer.parseInt(negativeId), fileVersion.getId()); } } catch (UpdateConflictException e) { errorConcernFiles |= e.isFile(); final ContainerInformation container = e.getContainer(); List<String> list = errors.get(container); if(list == null) { list = new ArrayList<>(); errors.put(container, list); } list.addAll(Arrays.asList(e.getParameters())); } } if (!errors.isEmpty()) { sendErrorsByMailToCurrentUser(errors, errorConcernFiles, context); } return new SynchronizeResult(errors, errorConcernFiles, files); } /** * Send errors of the synchronization by email. * * @param errors * Map of errors for each container (project or orgunit). * @param hasFiles * <code>true</code> if at least one error concern files. * @param context * Execution context. */ private void sendErrorsByMailToCurrentUser(Map<ContainerInformation, List<String>> errors, boolean hasFiles, UserDispatch.UserExecutionContext context) { // Full name. final String firstName = context.getUser().getFirstName(); final String lastName = context.getUser().getName(); final String fullName = firstName.isEmpty() ? lastName : firstName + ' ' + lastName; // Send the mail. final HashMap<EmailKey, String> parameters = new HashMap<>(); parameters.put(EmailKeyEnum.USER_USERNAME, fullName); parameters.put(EmailKeyEnum.ERROR_LIST, errorListBody(errors, hasFiles, context.getLanguage())); modelMailService.send(EmailType.OFFLINE_SYNC_CONFLICT, parameters, context.getLanguage(), context.getUser().getEmail()); } /** * Format the error list. * * @param errors * Map of errors for each container (project or orgunit). * @param hasFiles * <code>true</code> if at least one error concern files. * @param context * Execution context. * @return Body of the mail to be sent. */ private String errorListBody(Map<ContainerInformation, List<String>> errors, boolean hasFiles, Language language) { final StringBuilder ulBuilder = new StringBuilder(); for (final Map.Entry<ContainerInformation, List<String>> entry : errors.entrySet()) { if (entry.getKey().isProject()) { ulBuilder.append(i18nServer.t(language, "project")); } else { ulBuilder.append(i18nServer.t(language, "orgunit")); } ulBuilder.append(' ') .append(entry.getKey().getName()) .append(" - ") .append(entry.getKey().getFullName()) .append("<ul>"); for (final String error : entry.getValue()) { ulBuilder.append("<li>").append(error.replace("\n", "<br>")).append("</li>"); } ulBuilder.append("</ul>"); } if (hasFiles) { ulBuilder.append(i18nServer.t(language, "conflictFiles")); } return ulBuilder.toString(); } }