/*
* Copyright 2015-2017 Hewlett Packard Enterprise Development Company, L.P.
* Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
*/
package com.hp.autonomy.frontend.find.core.web;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hp.autonomy.frontend.configuration.ConfigService;
import com.hp.autonomy.frontend.find.core.beanconfiguration.AppConfiguration;
import com.hp.autonomy.frontend.find.core.configuration.FindConfig;
import com.hp.autonomy.frontend.find.core.configuration.UiCustomization;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import java.util.Locale;
import java.util.Optional;
import java.util.UUID;
import java.util.regex.Pattern;
@Component
@Slf4j
class ControllerUtilsImpl implements ControllerUtils {
private static final String MESSAGE_CODE_CONTACT_SUPPORT_UUID = "error.contactSupportUUID";
private static final String MESSAGE_CODE_CONTACT_SUPPORT_NO_UUID = "error.contactSupportNoUUID";
private static final String MESSAGE_CODE_ERROR_BUTTON = "error.button";
private static final Pattern JSON_ESCAPE_PATTERN = Pattern.compile("</", Pattern.LITERAL);
private final ObjectMapper objectMapper;
private final MessageSource messageSource;
private final String commit;
private final ConfigService<? extends FindConfig<?, ?>> configService;
@Autowired
public ControllerUtilsImpl(final ObjectMapper objectMapper, final MessageSource messageSource, @Value(AppConfiguration.GIT_COMMIT_PROPERTY) final String commit, final ConfigService<? extends FindConfig<?, ?>> configService) {
this.objectMapper = objectMapper;
this.messageSource = messageSource;
this.commit = commit;
this.configService = configService;
}
@Override
public String convertToJson(final Object object) throws JsonProcessingException {
// As we are inserting into a script tag escape </ to prevent injection
return JSON_ESCAPE_PATTERN.matcher(objectMapper.writeValueAsString(object)).replaceAll("<\\\\/");
}
@Override
public String getMessage(final String code, final Object[] args) throws NoSuchMessageException {
return messageSource.getMessage(code, args, Locale.ENGLISH);
}
@Override
public ModelAndView buildErrorModelAndView(final ErrorModelAndViewInfo errorInfo) {
final ModelAndView modelAndView = new ModelAndView(ViewNames.ERROR.viewName());
modelAndView.addObject(ErrorAttributes.MAIN_MESSAGE.value(),
errorInfo.getMainMessageCode() == null
? errorInfo.getMainMessage()
: getMessage(errorInfo.getMainMessageCode(), null));
modelAndView.addObject(ErrorAttributes.SUB_MESSAGE.value(),
errorInfo.getSubMessageCode() == null
? errorInfo.getSubMessage()
: getMessage(errorInfo.getSubMessageCode(), errorInfo.getSubMessageArguments()));
modelAndView.addObject(ErrorAttributes.BASE_URL.value(), RequestUtils.buildBaseUrl(errorInfo.getRequest()));
modelAndView.addObject(ErrorAttributes.STATUS_CODE.value(), errorInfo.getStatusCode());
modelAndView.addObject(ErrorAttributes.AUTH_ERROR.value(), errorInfo.isAuthError());
final String contactSupportMessage = Optional
.ofNullable(configService.getConfig().getUiCustomization())
.map(UiCustomization::getErrorCallSupportString)
.orElse(null);
if(errorInfo.isContactSupport()) {
if(errorInfo.getException() != null) {
final UUID uuid = UUID.randomUUID();
log.error("Unhandled exception with uuid {}", uuid);
log.error("Stack trace", errorInfo.getException());
modelAndView.addObject(ErrorAttributes.CONTACT_SUPPORT.value(),
contactSupportMessage == null
? getMessage(MESSAGE_CODE_CONTACT_SUPPORT_UUID, new Object[]{uuid})
: contactSupportMessage);
} else {
modelAndView.addObject(ErrorAttributes.CONTACT_SUPPORT.value(),
contactSupportMessage == null
? getMessage(MESSAGE_CODE_CONTACT_SUPPORT_NO_UUID, null)
: contactSupportMessage);
}
}
if(errorInfo.getButtonHref() != null) {
modelAndView.addObject(ErrorAttributes.BUTTON_HREF.value(), errorInfo.getButtonHref());
modelAndView.addObject(ErrorAttributes.BUTTON_MESSAGE.value(),
getMessage(MESSAGE_CODE_ERROR_BUTTON, null));
}
modelAndView.addObject(MvcConstants.GIT_COMMIT.value(), commit);
return modelAndView;
}
}