TemplateEngineRegistryDefaultImpl.java
/*
* This file is part of "albirar-template-engine".
*
* "albirar-template-engine" 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.
*
* "albirar-template-engine" 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 "albirar-template-engine" source code. If not, see <https://www.gnu.org/licenses/gpl-3.0.html>.
*
* Copyright (C) 2021 Octavi Fornés
*/
package cat.albirar.template.engine.registry;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import cat.albirar.template.engine.ITemplateEngineFactory;
import cat.albirar.template.engine.models.TemplateInstanceBean;
import cat.albirar.template.engine.service.IEngineRender;
import cat.albirar.template.engine.service.ITemplateEngine;
import cat.albirar.template.engine.service.ITemplateEngineRegistry;
import cat.albirar.template.engine.service.TemplateNotAccessibleException;
/**
* A default registry for {@link ITemplateEngine}.
* Any template engine should to be registered with {@link #register(ITemplateEngine)} method.
* @author Octavi Fornés <mailto:ofornes@albirar.cat[]>
* @since 2.2.0
*/
@Service
public class TemplateEngineRegistryDefaultImpl implements ITemplateEngineRegistry, ITemplateEngineFactory {
private static final Logger LOGGER = LoggerFactory.getLogger(TemplateEngineRegistryDefaultImpl.class);
@Autowired
private ApplicationContext applicationContext;
private Map<String, ITemplateEngine> engines = new HashMap<String, ITemplateEngine>();
/**
* {@inheritDoc}
*/
@Override
public Optional<ITemplateEngine> getTemplateEngine(@NotBlank String templateLanguage) {
LOGGER.debug("Search template engine for {} template language", templateLanguage);
return Optional.ofNullable(engines.get(templateLanguage));
}
/**
* {@inheritDoc}
*/
@Override
public List<String> getRegisteredTemplateLanguages() {
LOGGER.debug("Compound registered template languages list {}", engines.keySet());
return Collections.unmodifiableList(engines.keySet().stream().collect(Collectors.toList()));
}
/**
* {@inheritDoc}
*/
@Override
public void register(@NotNull @Valid ITemplateEngine templateEngine) {
LOGGER.debug("Register a new template engine for {} template language", templateEngine.getTemplateLanguage());
engines.put(templateEngine.getTemplateLanguage(), templateEngine);
}
/**
* {@inheritDoc}
*/
@Override
public String renderTemplate(@NotNull @Valid TemplateInstanceBean template) {
Optional<ITemplateEngine> te;
LOGGER.debug("Render template {} of {} template language", template.getName(), template.getTemplateEngineLanguage());
// Search the correct template engine by language and render
te = getTemplateEngine(template.getTemplateEngineLanguage());
// If exists, render can be made...
if(te.isPresent()) {
LOGGER.debug("Template engine for {} template language found, check resources...", template.getTemplateEngineLanguage());
// Check the preconditions of template itself...
checkResource(template.getTemplate());
LOGGER.debug("Template engine for {} template language found and resources checked, render it", template.getTemplateEngineLanguage());
// If all is ok, render it
return te.get().renderTemplate(template);
}
LOGGER.debug("Template engine for {} template language NOT FOUND!", template.getTemplateEngineLanguage());
// If no template engine was found, a exception should to be thrown
throw new IllegalStateException("No engine was registerd for the template language '".concat(template.getTemplateEngineLanguage()).concat("'"));
}
/**
* Checks the preconditions for the indicated {@code strResource} as established at {@link IEngineRender#renderTemplate(TemplateInstanceBean)}.
* @param strResource The resource to check
*/
private void checkResource(String strResource) {
Resource resource;
LOGGER.debug("Check resource {}", strResource);
resource = applicationContext.getResource(strResource);
if(!resource.exists()) {
LOGGER.error("Resource {} DOES NOT EXISTS!", strResource);
throw new TemplateNotAccessibleException(String.format("The resource '%s' does not exists!", strResource));
}
try {
if(!resource.getFile().isFile()) {
LOGGER.error("Resource {} IS NOT A FILE!", strResource);
throw new TemplateNotAccessibleException(String.format("The resource '%s' is not a regular file!", strResource));
}
}
catch(IOException e) {
LOGGER.error(String.format("IOException on get the file for resource %s!", strResource), e);
}
if(!resource.isReadable()) {
LOGGER.error("Resource {} IS NOT READABLE!", strResource);
throw new TemplateNotAccessibleException(String.format("The resource '%s' is not readable!", strResource));
}
LOGGER.debug("Resource {} IS OK!", strResource);
}
}