/*******************************************************************************
* Copyright (c) 2014 antoniomariasanchez at gmail.com.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* antoniomaria - initial API and implementation
******************************************************************************/
package net.sf.gazpachoquest.velocity.loader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.time.ZoneOffset;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sf.gazpachoquest.domain.core.MailMessageTemplate;
import net.sf.gazpachoquest.domain.core.embeddables.MailMessageTemplateLanguageSettings;
import net.sf.gazpachoquest.domain.i18.MailMessageTemplateTranslation;
import net.sf.gazpachoquest.qbe.SearchParameters;
import net.sf.gazpachoquest.repository.MailMessageTemplateRepository;
import net.sf.gazpachoquest.repository.i18.MailMessageTemplateTranslationRepository;
import net.sf.gazpachoquest.types.Language;
import org.apache.commons.collections.ExtendedProperties;
import org.apache.commons.lang.StringUtils;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.resource.Resource;
import org.apache.velocity.runtime.resource.loader.ResourceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class LocalizedTemplateResourceLoaderImpl extends ResourceLoader implements LocalizedTemplateResourceLoader {
private static final Logger logger = LoggerFactory.getLogger(LocalizedTemplateResourceLoaderImpl.class);
private static final Pattern SOURCE_NAME_PATTERN = Pattern.compile("^(?<templateId>\\d+)(/(?<language>[a-z]+))?$",
Pattern.CASE_INSENSITIVE);
@Autowired
private MailMessageTemplateRepository templateRepository;
@Autowired
private MailMessageTemplateTranslationRepository translationRepository;
/**
* @see org.apache.velocity.runtime.resource.loader.ResourceLoader#getLastModified(org.apache.velocity.runtime.resource.Resource)
*/
@Override
public long getLastModified(final Resource resource) {
return readLastModified(resource, "getting timestamp");
}
@Override
public InputStream getResourceStream(final String templateName) throws ResourceNotFoundException {
Integer templateId = readTemplateId(templateName);
Language language = readTemplateLanguage(templateName);
MailMessageTemplateLanguageSettings languageSettings = readLanguageSettings(templateId, language);
if (languageSettings == null) {
throw new ResourceNotFoundException("Template not found");
}
return new ByteArrayInputStream(languageSettings.getBody().getBytes(Charset.forName("UTF-8")));
}
@Override
public void init(final ExtendedProperties configuration) {
}
@Override
public boolean isCachingOn() {
return true;
}
@Override
public boolean isSourceModified(final Resource resource) {
return resource.getLastModified() != readLastModified(resource, "checking timestamp");
}
protected Integer readTemplateId(final String templateName) {
if (StringUtils.isEmpty(templateName)) {
throw new ResourceNotFoundException("DataSourceResourceLoader: Template name was empty or null");
}
Matcher matcher = SOURCE_NAME_PATTERN.matcher(templateName);
Integer templateId = null;
if (matcher.matches()) {
templateId = Integer.valueOf(matcher.group("templateId"));
} else {
throw new ResourceNotFoundException("Template name not valid. Pattern: templateId(/lang)?");
}
return templateId;
}
protected Language readTemplateLanguage(final String templateName) {
if (StringUtils.isEmpty(templateName)) {
throw new ResourceNotFoundException("DataSourceResourceLoader: Template name was empty or null");
}
Matcher matcher = SOURCE_NAME_PATTERN.matcher(templateName);
String languageStr = null;
if (matcher.matches()) {
languageStr = matcher.group("language");
} else {
throw new ResourceNotFoundException("Template name not valid. Pattern: templateId(/lang)?");
}
Language language = null;
if (StringUtils.isNotBlank(languageStr)) {
language = Language.valueOf(languageStr);
if (language == null) {
throw new ResourceNotFoundException("Language not supported");
}
}
return language;
}
private MailMessageTemplateLanguageSettings readLanguageSettings(final Integer templateId, final Language language) {
MailMessageTemplateLanguageSettings languageSettings = null;
MailMessageTemplate template = templateRepository.findOne(templateId);
if (template != null) {
if (template.getLanguage().equals(language)) {
languageSettings = template.getLanguageSettings();
} else {
MailMessageTemplateTranslation example = new MailMessageTemplateTranslation();
example.setLanguage(language);
example.setMailMessageTemplate(MailMessageTemplate.with().id(templateId).build());
List<MailMessageTemplateTranslation> translations = translationRepository.findByExample(example,
new SearchParameters());
if (translations != null && !translations.isEmpty()) {
languageSettings = translations.get(0).getLanguageSettings();
} else {
languageSettings = template.getLanguageSettings();
logger.warn("No translation in " + language
+ " for MailMessageTemplate {}, providing default language", templateId);
}
}
}
return languageSettings;
}
private long readLastModified(final Resource resource, final String operation) {
String templateName = resource.getName();
Integer templateId = readTemplateId(templateName);
logger.info("{} from mail message template {} ", operation, templateId);
MailMessageTemplate template = templateRepository.findOne(templateId);
return template.getLastModifiedDate().toEpochSecond(ZoneOffset.UTC);
}
}