1//
2// TemplateCache.cpp
3//
4// Library: JSON
5// Package: JSON
6// Module: TemplateCache
7//
8// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/File.h"
16#include "Poco/Format.h"
17#include "Poco/JSON/TemplateCache.h"
18
19
20namespace Poco {
21namespace JSON {
22
23
24TemplateCache* TemplateCache::_pInstance = 0;
25
26
27TemplateCache::TemplateCache()
28{
29 setup();
30}
31
32
33TemplateCache::~TemplateCache()
34{
35 _pInstance = 0;
36}
37
38
39void TemplateCache::setup()
40{
41 poco_assert (_pInstance == 0);
42 _pInstance = this;
43}
44
45
46Template::Ptr TemplateCache::getTemplate(const Path& path)
47{
48 if (_pLogger)
49 {
50 _pLogger->trace("Trying to load %s", path.toString());
51 }
52
53 Path templatePath = resolvePath(path);
54 std::string templatePathname = templatePath.toString();
55
56 if (_pLogger)
57 {
58 _pLogger->trace("Path resolved to %s", templatePathname);
59 }
60
61 File templateFile(templatePathname);
62
63 Template::Ptr tpl;
64
65 std::map<std::string, Template::Ptr>::iterator it = _cache.find(templatePathname);
66 if (it == _cache.end())
67 {
68 if (templateFile.exists())
69 {
70 if (_pLogger)
71 {
72 _pLogger->information("Loading template %s", templatePath.toString());
73 }
74
75 tpl = new Template(templatePath);
76
77 try
78 {
79 tpl->parse();
80 _cache[templatePathname] = tpl;
81 }
82 catch (JSONTemplateException& jte)
83 {
84 if (_pLogger)
85 {
86 _pLogger->error("Template %s contains an error: %s", templatePath.toString(), jte.message());
87 }
88 }
89 }
90 else
91 {
92 if (_pLogger)
93 {
94 _pLogger->error("Template file %s doesn't exist", templatePath.toString());
95 }
96 throw FileNotFoundException(templatePathname);
97 }
98 }
99 else
100 {
101 tpl = it->second;
102 if (tpl->parseTime() < templateFile.getLastModified())
103 {
104 if (_pLogger)
105 {
106 _pLogger->information("Reloading template %s", templatePath.toString());
107 }
108
109 tpl = new Template(templatePath);
110
111 try
112 {
113 tpl->parse();
114 _cache[templatePathname] = tpl;
115 }
116 catch (JSONTemplateException& jte)
117 {
118 if (_pLogger)
119 {
120 _pLogger->error("Template %s contains an error: %s", templatePath.toString(), jte.message());
121 }
122 }
123 }
124 }
125
126 return tpl;
127}
128
129
130Path TemplateCache::resolvePath(const Path& path) const
131{
132 if (path.isAbsolute())
133 return path;
134
135 for (std::vector<Path>::const_iterator it = _includePaths.begin(); it != _includePaths.end(); ++it)
136 {
137 Path templatePath(*it, path);
138
139 File templateFile(templatePath);
140 if (templateFile.exists())
141 {
142 if (_pLogger)
143 {
144 _pLogger->trace("%s template file resolved to %s", path.toString(), templatePath.toString());
145 }
146 return templatePath;
147 }
148 if (_pLogger)
149 {
150 _pLogger->trace("%s doesn't exist", templatePath.toString());
151 }
152 }
153
154 throw FileNotFoundException(path.toString());
155}
156
157
158} } // Poco::JSON
159