use std::sync::Arc;
use crate::TemplateResolutionAttributes;
use crate::cache::{
AlwaysValidCacheEntryValidity, ICacheEntryValidity, NonCacheableCacheEntryValidity,
TTLCacheEntryValidity,
};
use crate::exceptions::ConfigurationException;
use crate::util::Utf16String;
use crate::{
IEngineConfiguration, ITemplateResource, StringTemplateResource, TemplateMode,
TemplateModeParseError,
};
use super::{
AbstractTemplateResolver, ITemplateResolver, TemplateResolution, TemplateResolverError,
};
pub struct StringTemplateResolver {
resolver: AbstractTemplateResolver,
template_mode: TemplateMode,
cacheable: bool,
cache_ttl_ms: Option<i64>,
}
impl StringTemplateResolver {
pub const DEFAULT_TEMPLATE_MODE: TemplateMode = TemplateMode::HTML;
pub const DEFAULT_CACHEABLE: bool = false;
pub const DEFAULT_CACHE_TTL_MS: Option<i64> = None;
#[must_use]
pub fn new() -> Self {
Self {
resolver: AbstractTemplateResolver::new(
"org.thymeleaf.templateresolver.StringTemplateResolver",
),
template_mode: Self::DEFAULT_TEMPLATE_MODE,
cacheable: Self::DEFAULT_CACHEABLE,
cache_ttl_ms: Self::DEFAULT_CACHE_TTL_MS,
}
}
#[must_use]
pub const fn get_template_mode(&self) -> TemplateMode {
self.template_mode
}
pub const fn set_template_mode(&mut self, template_mode: TemplateMode) {
self.template_mode = template_mode;
}
pub fn set_template_mode_nullable(
&mut self,
template_mode: Option<TemplateMode>,
) -> Result<(), TemplateResolverError> {
self.template_mode = template_mode.ok_or_else(|| {
TemplateResolverError::InvalidArgument(
"Cannot set a null template mode value".to_owned(),
)
})?;
Ok(())
}
pub fn set_template_mode_name(
&mut self,
template_mode: Option<&str>,
) -> Result<(), TemplateResolverError> {
let template_mode = template_mode.ok_or_else(|| {
TemplateResolverError::InvalidArgument(
"Cannot set a null template mode value".to_owned(),
)
})?;
self.template_mode =
TemplateMode::parse(Some(template_mode)).map_err(|error: TemplateModeParseError| {
TemplateResolverError::InvalidArgument(error.to_string())
})?;
Ok(())
}
#[must_use]
pub const fn is_cacheable(&self) -> bool {
self.cacheable
}
pub const fn set_cacheable(&mut self, cacheable: bool) {
self.cacheable = cacheable;
}
#[must_use]
pub const fn get_cache_ttl_ms(&self) -> Option<i64> {
self.cache_ttl_ms
}
pub const fn set_cache_ttl_ms(&mut self, cache_ttl_ms: Option<i64>) {
self.cache_ttl_ms = cache_ttl_ms;
}
pub fn set_use_decoupled_logic(
&mut self,
use_decoupled_logic: bool,
) -> Result<(), ConfigurationException> {
if use_decoupled_logic {
return Err(ConfigurationException::new(Some(
"The 'useDecoupledLogic' flag is not allowed for String template resolution"
.to_owned(),
)));
}
self.resolver.set_use_decoupled_logic(false);
Ok(())
}
fn compute_validity(&self) -> Arc<dyn ICacheEntryValidity> {
if !self.cacheable {
return Arc::new(NonCacheableCacheEntryValidity::new());
}
self.cache_ttl_ms.map_or_else(
|| Arc::new(AlwaysValidCacheEntryValidity::new()) as Arc<dyn ICacheEntryValidity>,
|ttl| Arc::new(TTLCacheEntryValidity::new(ttl)),
)
}
}
impl Default for StringTemplateResolver {
fn default() -> Self {
Self::new()
}
}
impl std::ops::Deref for StringTemplateResolver {
type Target = AbstractTemplateResolver;
fn deref(&self) -> &Self::Target {
&self.resolver
}
}
impl std::ops::DerefMut for StringTemplateResolver {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.resolver
}
}
impl ITemplateResolver for StringTemplateResolver {
fn get_name(&self) -> Option<&Utf16String> {
self.resolver.get_name()
}
fn get_order(&self) -> Option<i32> {
self.resolver.get_order()
}
fn resolve_template(
&self,
_configuration: &dyn IEngineConfiguration,
_owner_template: Option<&Utf16String>,
template: &Utf16String,
_template_resolution_attributes: Option<&TemplateResolutionAttributes>,
) -> Result<Option<TemplateResolution>, TemplateResolverError> {
self.resolver.resolve_template(
template,
|| {
StringTemplateResource::new(Some(&template.to_string_lossy()))
.map(|resource| Some(Arc::new(resource) as Arc<dyn ITemplateResource>))
.map_err(TemplateResolverError::from)
},
|| self.template_mode,
|| self.compute_validity(),
)
}
}