Commit 81d5a72afed3b9466185ce55d625447ee030a4a5

Merge EngineState into Engine.

If applications will want multiple engine states it makes more sense
for them to store engines than states.

This way Engine is not a singleton anymore which means that it needs
to be passed around more.
  
1212set (grantlee_core_SRCS
1313 context.cpp
1414 engine.cpp
15 enginestate.cpp
1615 filterexpression.cpp
1716 lexer.cpp
1817 mutabletemplate.cpp
5252install(FILES
5353 context.h
5454 engine.h
55 enginestate.h
5655 exception.h
5756 filter.h
5857 filterexpression.h
  
2626#include <QPluginLoader>
2727
2828#include "taglibraryinterface.h"
29#include "enginestate_p.h"
3029#include "template_p.h"
3130#include "templateloader.h"
3231#include "grantlee_version.h"
5959
6060};
6161
62Engine* Engine::m_instance = 0;
63Engine* Engine::instance()
62Engine::Engine( QObject *parent )
63 : QObject( parent ), d_ptr( new EnginePrivate( this ) )
6464{
65 if ( !m_instance ) {
66 m_instance = new Engine();
67 }
68 return m_instance;
65 d_ptr->m_defaultLibraries << "grantlee_defaulttags"
66 << "grantlee_loadertags"
67 << "grantlee_defaultfilters"
68 << "grantlee_scriptabletags";
6969}
7070
71Engine::Engine()
72 : d_ptr( new EnginePrivate( this ) )
73{
74}
75
7671Engine::~Engine()
7772{
7873 qDeleteAll( d_ptr->m_scriptableLibraries );
7676 pluginLoader->unload();
7777 qDeleteAll(d_ptr->m_pluginLoaders);
7878 delete d_ptr;
79 m_instance = 0;
8079}
8180
8281QList<AbstractTemplateLoader::Ptr> Engine::templateLoaders()
8382{
8483 Q_D( Engine );
85 return d->m_currentState->d_ptr->m_loaders;
84 return d->m_loaders;
8685}
8786
8887void Engine::addTemplateLoader( AbstractTemplateLoader::Ptr loader )
8988{
9089 Q_D( Engine );
91 d->m_currentState->d_ptr->m_loaders << loader;
90 d->m_loaders << loader;
9291}
9392
94QString Engine::mediaUri( const QString &fileName, const EngineState &_state ) const
93QString Engine::mediaUri( const QString &fileName ) const
9594{
9695 Q_D( const Engine );
97 EngineState state = _state ? _state : d->m_currentState;
98 QListIterator<AbstractTemplateLoader::Ptr> it( state->d_ptr->m_loaders );
96 QListIterator<AbstractTemplateLoader::Ptr> it( d->m_loaders );
9997
10098 QString uri;
10199 while ( it.hasNext() ) {
108108void Engine::setPluginDirs( const QStringList &dirs )
109109{
110110 Q_D( Engine );
111 d->m_currentState->d_ptr->m_pluginDirs = dirs;
111 d->m_pluginDirs = dirs;
112112}
113113
114114QStringList Engine::defaultLibraries() const
115115{
116116 Q_D( const Engine );
117 return d->m_currentState->d_ptr->m_defaultLibraries;
117 return d->m_defaultLibraries;
118118}
119119
120120void Engine::addDefaultLibrary( const QString &libName )
121121{
122122 Q_D( Engine );
123 d->m_currentState->d_ptr->m_defaultLibraries << libName;
123 d->m_defaultLibraries << libName;
124124}
125125
126126void Engine::removeDefaultLibrary( const QString &libName )
127127{
128128 Q_D( Engine );
129 d->m_currentState->d_ptr->m_defaultLibraries.removeAll( libName );
129 d->m_defaultLibraries.removeAll( libName );
130130}
131131
132void Engine::loadDefaultLibraries( const EngineState &_state )
132void Engine::loadDefaultLibraries()
133133{
134134 Q_D( Engine );
135 EngineState state = _state ? _state : d->m_currentState;
136135 // Make sure we can load default scriptable libraries if we're supposed to.
137 if ( state->d_ptr->m_defaultLibraries.contains( __scriptableLibName ) ) {
138 d->loadCppLibrary( __scriptableLibName, GRANTLEE_VERSION_MINOR, state );
136 if ( d->m_defaultLibraries.contains( __scriptableLibName ) ) {
137 TagLibraryInterface *library = d->loadCppLibrary( __scriptableLibName, GRANTLEE_VERSION_MINOR );
138 if ( library )
139 {
140 library->setEngine( this );
141 }
139142 }
140143
141 foreach( const QString &libName, state->d_ptr->m_defaultLibraries ) {
144 foreach( const QString &libName, d->m_defaultLibraries ) {
142145 if ( libName == __scriptableLibName )
143146 continue;
144147
145 TagLibraryInterface *library = loadLibrary( libName, state );
148 TagLibraryInterface *library = loadLibrary( libName );
146149 if ( !library )
147150 continue;
148151 }
149152}
150153
151TagLibraryInterface* Engine::loadLibrary( const QString &name, const EngineState &_state )
154TagLibraryInterface* Engine::loadLibrary( const QString &name )
152155{
153156 Q_D( Engine );
154 EngineState state = _state ? _state : d->m_currentState;
155157
156158 if ( name == __scriptableLibName )
157159 return 0;
165165 uint minorVersion = GRANTLEE_VERSION_MINOR;
166166 while ( minorVersion >= GRANTLEE_MIN_PLUGIN_VERSION )
167167 {
168 TagLibraryInterface* library = d->loadLibrary( name, state, minorVersion-- );
168 TagLibraryInterface* library = d->loadLibrary( name, minorVersion-- );
169169 if ( library )
170170 return library;
171171 }
172172 return 0;
173173}
174174
175TagLibraryInterface* EnginePrivate::loadLibrary( const QString &name, const EngineState &state, uint minorVersion )
175TagLibraryInterface* EnginePrivate::loadLibrary( const QString &name, uint minorVersion )
176176{
177 TagLibraryInterface* scriptableLibrary = loadScriptableLibrary( name, minorVersion, state );
177 TagLibraryInterface* scriptableLibrary = loadScriptableLibrary( name, minorVersion );
178178 if ( scriptableLibrary )
179179 return scriptableLibrary;
180180
181181 // else this is not a scriptable library.
182182
183 return loadCppLibrary( name, minorVersion, state );
183 return loadCppLibrary( name, minorVersion );
184184}
185185
186186EnginePrivate::EnginePrivate( Engine *engine )
187187 : q_ptr( engine )
188188{
189 m_currentState = staticEmptyState();
190189}
191190
192TagLibraryInterface* EnginePrivate::loadScriptableLibrary( const QString &name, uint minorVersion, const EngineState &_state )
191TagLibraryInterface* EnginePrivate::loadScriptableLibrary( const QString &name, uint minorVersion )
193192{
194 EngineState state = _state ? _state : m_currentState;
195
196193 int pluginIndex = 0;
197194 QString libFileName;
198195 if ( !m_libraries.contains( __scriptableLibName ) )
199196 return 0;
200197
201 while ( state->d_ptr->m_pluginDirs.size() > pluginIndex ) {
202 QString nextDir = state->d_ptr->m_pluginDirs.at( pluginIndex++ );
198 while ( m_pluginDirs.size() > pluginIndex ) {
199 QString nextDir = m_pluginDirs.at( pluginIndex++ );
203200 libFileName = nextDir + QString( "/%1.%2" ).arg( GRANTLEE_VERSION_MAJOR ).arg( minorVersion ) + '/' + name + ".qs";
204201 QFile file( libFileName );
205202 if ( !file.exists() )
211211 m_scriptableLibraries << library;
212212 return library;
213213 }
214
215214 return 0;
216215}
217216
218TagLibraryInterface* EnginePrivate::loadCppLibrary( const QString &name, uint minorVersion, const EngineState &_state )
217TagLibraryInterface* EnginePrivate::loadCppLibrary( const QString &name, uint minorVersion )
219218{
220219 Q_Q( Engine );
221 EngineState state = _state ? _state : m_currentState;
222
223220 int pluginIndex = 0;
224221 QString libFileName;
225222
226223 QObject *plugin = 0;
227 while ( state->d_ptr->m_pluginDirs.size() > pluginIndex ) {
228 QString nextDir = state->d_ptr->m_pluginDirs.at( pluginIndex++ );
224 while ( m_pluginDirs.size() > pluginIndex ) {
225 QString nextDir = m_pluginDirs.at( pluginIndex++ );
229226 QDir pluginDir( nextDir + QString( "/%1.%2" ).arg( GRANTLEE_VERSION_MAJOR ).arg( minorVersion ) + '/' );
230227
231228 if ( !pluginDir.exists() )
249249 return library;
250250}
251251
252Template Engine::loadByName( const QString &name, const EngineState &_state ) const
252Template Engine::loadByName( const QString &name ) const
253253{
254254 Q_D( const Engine );
255255
256 EngineState state = _state ? _state : d->m_currentState;
257
258 QListIterator<AbstractTemplateLoader::Ptr> it( state->d_ptr->m_loaders );
256 QListIterator<AbstractTemplateLoader::Ptr> it( d->m_loaders );
259257 while ( it.hasNext() ) {
260258 AbstractTemplateLoader::Ptr loader = it.next();
261259
262260 if ( !loader->canLoadTemplate( name ) )
263261 continue;
264262
265 Template t = loader->loadByName( name );
263 Template t = loader->loadByName( name, this );
266264
267265 if ( t ) {
268 t->d_ptr->m_state = state;
269266 return t;
270267 }
271268 }
272 throw Grantlee::Exception( TagSyntaxError, QString( "Most recent state is invalid." ) );
269 return Template();
273270}
274271
275MutableTemplate Engine::loadMutableByName( const QString &name, const EngineState &_state ) const
272MutableTemplate Engine::loadMutableByName( const QString &name ) const
276273{
277274 Q_D( const Engine );
278275
279 EngineState state = _state ? _state : d->m_currentState;
276 QListIterator<AbstractTemplateLoader::Ptr> it( d->m_loaders );
280277
281 QListIterator<AbstractTemplateLoader::Ptr> it( state->d_ptr->m_loaders );
282
283278 while ( it.hasNext() ) {
284279 AbstractTemplateLoader::Ptr loader = it.next();
285 MutableTemplate t = loader->loadMutableByName( name );
280 MutableTemplate t = loader->loadMutableByName( name, this );
286281 if ( t ) {
287 t->d_ptr->m_state = state;
288282 return t;
289283 }
290284 }
291285 throw Grantlee::Exception( TagSyntaxError, QString( "Most recent state is invalid." ) );
292286}
293287
294MutableTemplate Engine::newMutableTemplate( const QString &content, const QString &name, const EngineState &_state ) const
288MutableTemplate Engine::newMutableTemplate( const QString &content, const QString &name ) const
295289{
296 Q_D( const Engine );
297 EngineState state = _state ? _state : d->m_currentState;
298
299 MutableTemplate t = MutableTemplate( new MutableTemplateImpl() );
290 MutableTemplate t = MutableTemplate( new MutableTemplateImpl( this ) );
300291 t->setObjectName( name );
301 t->d_ptr->m_state = state;
302292 t->setContent( content );
303293 return t;
304294}
305295
306Template Engine::newTemplate( const QString &content, const QString &name, const EngineState &_state ) const
296Template Engine::newTemplate( const QString &content, const QString &name ) const
307297{
308 Q_D( const Engine );
309 EngineState state = _state ? _state : d->m_currentState;
310
311 Template t = Template( new TemplateImpl() );
312
298 Template t = Template( new TemplateImpl( this ) );
313299 t->setObjectName( name );
314 t->d_ptr->m_state = state;
315300 t->setContent( content );
316301 return t;
317302}
318303
319void Engine::resetState()
320{
321 Q_D( Engine );
322 // set the default empty state.
323 d->m_currentState = d->staticEmptyState();
324}
325
326EngineState EnginePrivate::staticEmptyState()
327{
328 static EngineState state = EngineState( new EngineStateImpl() );
329 return state;
330}
304#include "engine.moc"
  
6262 @author Stephen Kelly <steveire@gmail.com>
6363 @since 0.1
6464*/
65class GRANTLEE_CORE_EXPORT Engine
65class GRANTLEE_CORE_EXPORT Engine : public QObject
6666{
67 Q_OBJECT
6768public:
6869 /**
6970 Retrieve an instance of an Engine.
7071 */
71 static Engine* instance();
72 Engine( QObject *parent = 0 );
7273
7374 /**
7475 Destructor.
101101 This method will not usually be called by application code.
102102 To load media in a template, use the {% media_finder %} template tag.
103103 */
104 QString mediaUri( const QString &fileName, const EngineState &state = EngineState() ) const;
104 QString mediaUri( const QString &fileName ) const;
105105
106106 /**
107107 Resets the state of the Engine to the default.
116116
117117 The Templates and plugins loaded and will be determined by the Engine or the EngineState @p state.
118118 */
119 Template loadByName( const QString &name, const EngineState &state = EngineState() ) const;
119 Template loadByName( const QString &name ) const;
120120
121121 /**
122122 Create a new Template with the content @p content identified by @p name with the optionally supplied EngineState.
123123
124124 The secondary Templates and plugins loaded will be determined by the Engine or the EngineState @p state.
125125 */
126 Template newTemplate( const QString &content, const QString &name, const EngineState &state = EngineState() ) const;
126 Template newTemplate( const QString &content, const QString &name ) const;
127127
128128 /**
129129 Load the MutableTemplate identified by @p name with the optionally supplied EngineState.
130130
131131 The Templates and plugins loaded and will be determined by the Engine or the EngineState @p state.
132132 */
133 MutableTemplate loadMutableByName( const QString &name, const EngineState &state = EngineState() ) const;
133 MutableTemplate loadMutableByName( const QString &name ) const;
134134
135135 /**
136136 Create a new MutableTemplate with the content @p content identified by @p name with the optionally supplied EngineState.
137137
138138 The secondary Templates and plugins loaded will be determined by the Engine or the EngineState @p state.
139139 */
140 MutableTemplate newMutableTemplate( const QString &content, const QString &name, const EngineState &state = EngineState() ) const;
140 MutableTemplate newMutableTemplate( const QString &content, const QString &name ) const;
141141
142142 /**
143143 Returns the libraries available by default to new Templates.
159159
160160 Loads and returns the libraries specified in defaultLibraries or @p state.
161161 */
162 void loadDefaultLibraries( const EngineState &state = EngineState() );
162 void loadDefaultLibraries();
163163
164164 /**
165165 @internal
168168
169169 Templates wishing to load a library should use the "{% load %}" tag.
170170 */
171 TagLibraryInterface* loadLibrary( const QString &name, const EngineState &state = EngineState() );
171 TagLibraryInterface* loadLibrary( const QString &name );
172172
173 /**
174 Returns the current state of the Engine.
175 @see template_factories
176 */
177 EngineState state();
178
179private:
180 Engine();
181
182173 Q_DECLARE_PRIVATE( Engine )
183174 EnginePrivate * const d_ptr;
184
185 static Engine* m_instance;
186175};
187176
188177}
  
2222#define GRANTLEE_ENGINE_P_H
2323
2424#include "engine.h"
25#include "enginestate_p.h"
2625
2726class QPluginLoader;
2827
28class QPluginLoader;
29
2930namespace Grantlee
3031{
3132
3434{
3535 EnginePrivate( Engine *engine );
3636
37 static EngineState staticEmptyState();
37 TagLibraryInterface* loadLibrary( const QString &name, uint minorVersion );
38 TagLibraryInterface* loadScriptableLibrary( const QString &name, uint minorVersion );
39 TagLibraryInterface* loadCppLibrary( const QString& name, uint minorVersion );
3840
39 TagLibraryInterface* loadLibrary( const QString &name, const EngineState &state, uint minorVersion );
40 TagLibraryInterface* loadScriptableLibrary( const QString &name, uint minorVersion, const EngineState &state = EngineState() );
41 TagLibraryInterface* loadCppLibrary( const QString& name, uint minorVersion, const EngineState &state = EngineState() );
42
4341 Q_DECLARE_PUBLIC( Engine )
4442 Engine *q_ptr;
4543
46 EngineState m_currentState;
47
4844 QList<QPluginLoader*> m_pluginLoaders;
45
4946 QHash<QString, TagLibraryInterface*> m_libraries;
5047 QList<TagLibraryInterface*> m_scriptableLibraries;
5148
52 friend class EngineStateImpl;
49 QList<AbstractTemplateLoader::Ptr> m_loaders;
50 QStringList m_pluginDirs;
51 QStringList m_defaultLibraries;
5352};
5453
5554}
  
1/*
2 This file is part of the Grantlee template system.
3
4 Copyright (c) 2009 Stephen Kelly <steveire@gmail.com>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License version 3 only, as published by the Free Software Foundation.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License version 3 for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library. If not, see <http://www.gnu.org/licenses/>.
17
18*/
19
20#include "enginestate.h"
21#include "enginestate_p.h"
22
23#include "engine.h"
24#include "engine_p.h"
25
26using namespace Grantlee;
27
28EngineStateImpl::EngineStateImpl()
29 : d_ptr( new EngineStateImplPrivate() )
30{
31 Q_D( EngineStateImpl );
32 d->m_defaultLibraries << "grantlee_defaulttags"
33 << "grantlee_loadertags"
34 << "grantlee_defaultfilters"
35 << "grantlee_scriptabletags";
36}
37
38Grantlee::EngineStateImpl::~EngineStateImpl()
39{
40 delete d_ptr;
41}
  
1/*
2 This file is part of the Grantlee template system.
3
4 Copyright (c) 2009 Stephen Kelly <steveire@gmail.com>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License version 3 only, as published by the Free Software Foundation.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License version 3 for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library. If not, see <http://www.gnu.org/licenses/>.
17
18*/
19
20#ifndef GRANTLEE_ENGINE_STATE_H
21#define GRANTLEE_ENGINE_STATE_H
22
23#include <QtCore/QSharedPointer>
24
25#include "grantlee_core_export.h"
26
27namespace Grantlee
28{
29
30class EngineStateImplPrivate;
31
32/**
33 @brief The EngineStateImpl class stores a particular configuration for an Engine.
34
35 This class deliberately does not have any public API. All EngineStates should be configured and retrieved using API
36 on the Engine class.
37
38 @see template_factories
39*/
40class GRANTLEE_CORE_EXPORT EngineStateImpl
41{
42public:
43 ~EngineStateImpl();
44private:
45 friend class Engine;
46 friend class EnginePrivate;
47
48 Q_DECLARE_PRIVATE( EngineStateImpl )
49 EngineStateImplPrivate * const d_ptr;
50
51 EngineStateImpl();
52};
53
54typedef QWeakPointer<EngineStateImpl> EngineStateWeakPtr;
55typedef QSharedPointer<EngineStateImpl> EngineState;
56
57}
58
59#endif
  
1/*
2 This file is part of the Grantlee template system.
3
4 Copyright (c) 2009 Stephen Kelly <steveire@gmail.com>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License version 3 only, as published by the Free Software Foundation.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License version 3 for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library. If not, see <http://www.gnu.org/licenses/>.
17
18*/
19
20#ifndef GRANTLEE_ENGINE_STATE_P_H
21#define GRANTLEE_ENGINE_STATE_P_H
22
23#include "enginestate.h"
24#include "templateloader.h"
25
26namespace Grantlee
27{
28
29class EngineStateImplPrivate
30{
31 Q_DECLARE_PUBLIC( EngineStateImpl )
32 EngineStateImpl *q_ptr;
33
34 QList<AbstractTemplateLoader::Ptr> m_loaders;
35 QStringList m_pluginDirs;
36 QStringList m_defaultLibraries;
37
38 friend class Engine;
39 friend class EnginePrivate;
40
41};
42
43}
44
45#endif
  
2121
2222using namespace Grantlee;
2323
24MutableTemplateImpl::MutableTemplateImpl( QObject *parent )
25 : TemplateImpl( parent )
24MutableTemplateImpl::MutableTemplateImpl( Engine const *engine, QObject *parent )
25 : TemplateImpl( engine, parent )
2626{
2727
2828}
  
3939 /**
4040 Constructor.
4141 */
42 explicit MutableTemplateImpl( QObject *parent = 0 );
42 explicit MutableTemplateImpl( Engine const *engine, QObject *parent = 0 );
4343
4444 /**
4545 Renders the Template, possibly mutating it.
  
2323
2424#include "taglibraryinterface.h"
2525#include "template.h"
26#include "template_p.h"
2627#include "engine.h"
2728#include "filter.h"
2829#include "exception.h"
8686{
8787 Q_D( Parser );
8888
89 Engine *engine = Engine::instance();
90
9189 TemplateImpl *ti = qobject_cast<TemplateImpl *>( parent );
9290
93 engine->loadDefaultLibraries( ti->state() );
94 foreach( const QString &libraryName, engine->defaultLibraries()) {
95 TagLibraryInterface *library = engine->loadLibrary( libraryName, ti->state() );
91 Engine const *cengine = ti->engine();
92 if (!cengine)
93 return;
94 Engine *engine = const_cast<Engine *>( cengine );
95 engine->loadDefaultLibraries();
96 foreach( const QString &libraryName, engine->defaultLibraries() ) {
97 TagLibraryInterface *library = engine->loadLibrary( libraryName );
9698 if(!library)
9799 continue;
98100 d->openLibrary( library );
121121{
122122 Q_D( Parser );
123123 TemplateImpl *ti = qobject_cast<TemplateImpl *>( parent() );
124 TagLibraryInterface *library = Engine::instance()->loadLibrary( name, ti->state() );
124 Engine const *cengine = ti->engine();
125 if (!cengine)
126 return;
127 Engine *engine = const_cast<Engine *>( cengine );
128 TagLibraryInterface *library = engine->loadLibrary( name );
125129 if ( !library )
126130 return;
127131 d->openLibrary( library );
  
3737 return p.parse( q );
3838}
3939
40TemplateImpl::TemplateImpl( QObject *parent )
41 : QObject( parent ), d_ptr( new TemplatePrivate( this ) )
40TemplateImpl::TemplateImpl( Engine const *engine, QObject *parent )
41 : QObject( parent ), d_ptr( new TemplatePrivate( engine, this ) )
4242{
4343 Q_D( Template );
4444 d->m_settingsToken = reinterpret_cast<qint64>( this );
107107 return d->m_errorString;
108108}
109109
110EngineState TemplateImpl::state() const
110Engine const * TemplateImpl::engine() const
111111{
112112 Q_D( const Template );
113 return d->m_state;
113 return d->m_engine.data();
114114}
115115
116116#include "template.moc"
  
2323#include <QtCore/QStringList>
2424#include <QtCore/QSharedPointer>
2525
26#include "enginestate.h"
2726#include "node.h"
2827
2928#include "global.h"
3131namespace Grantlee
3232{
3333class Context;
34class Engine;
3435class TemplateImpl;
3536
3637typedef QWeakPointer<TemplateImpl> TemplateWeakPtr;
8181 */
8282 QString errorString();
8383
84 /**
85 The state used and accessed while parsing and rendering the Template.
86 */
87 EngineState state() const;
84 Engine const * engine() const;
8885
8986protected:
90 TemplateImpl( QObject *parent = 0 );
87 TemplateImpl( Engine const *engine, QObject *parent = 0 );
9188
9289 void setContent( const QString &templateString );
9390
9292 Q_DECLARE_PRIVATE( Template )
9393 TemplatePrivate * const d_ptr;
9494 friend class Engine;
95 friend class Parser;
9596};
9697
9798}
  
2222
2323#include "template.h"
2424
25#include "enginestate_p.h"
25#include "engine.h"
2626
2727namespace Grantlee
2828{
3131
3232class TemplatePrivate
3333{
34 TemplatePrivate( TemplateImpl *t )
35 : q_ptr( t ), m_error( NoError ) {
34 TemplatePrivate( Engine const *engine, TemplateImpl *t )
35 : q_ptr( t ), m_error( NoError ), m_engine( engine )
36 {
3637
3738 }
3839
4848 Error m_error;
4949 QString m_errorString;
5050 NodeList m_nodeList;
51 EngineState m_state;
51 QWeakPointer<Engine const> m_engine;
5252
5353 friend class Grantlee::Engine;
54 friend class Parser;
5455
5556};
5657
  
9090}
9191
9292// TODO Refactor these two.
93MutableTemplate FileSystemTemplateLoader::loadMutableByName( const QString &fileName ) const
93MutableTemplate FileSystemTemplateLoader::loadMutableByName( const QString &fileName, Engine const *engine ) const
9494{
9595 int i = 0;
9696 QFile file;
114114 QString content;
115115 content = file.readAll();
116116
117 MutableTemplate t = Engine::instance()->newMutableTemplate( content, fileName );
117 MutableTemplate t = engine->newMutableTemplate( content, fileName );
118118 return t;
119119}
120120
121Template FileSystemTemplateLoader::loadByName( const QString &fileName ) const
121Template FileSystemTemplateLoader::loadByName( const QString &fileName, Engine const *engine ) const
122122{
123123 int i = 0;
124124 QFile file;
140140
141141 QString content;
142142 content = file.readAll();
143 Template t = Engine::instance()->newTemplate( content, fileName );
143 Template t = engine->newTemplate( content, fileName );
144144 return t;
145145}
146146
178178 return m_namedTemplates.contains( name );
179179}
180180
181Template InMemoryTemplateLoader::loadByName( const QString& name ) const
181Template InMemoryTemplateLoader::loadByName( const QString& name, Engine const *engine ) const
182182{
183183 if ( m_namedTemplates.contains( name ) ) {
184 Template t = Engine::instance()->newTemplate( m_namedTemplates.value( name ), name );
184 Template t = engine->newTemplate( m_namedTemplates.value( name ), name );
185185 return t;
186186 }
187187 throw Grantlee::Exception( TagSyntaxError, QString( "Couldn't load template %1. Template does not exist." ).arg( name ) );
188188}
189189
190MutableTemplate InMemoryTemplateLoader::loadMutableByName( const QString& name ) const
190MutableTemplate InMemoryTemplateLoader::loadMutableByName( const QString& name, Engine const *engine ) const
191191{
192192 if ( m_namedTemplates.contains( name ) ) {
193 MutableTemplate t = Engine::instance()->newMutableTemplate( m_namedTemplates.value( name ), name );
193 MutableTemplate t = engine->newMutableTemplate( m_namedTemplates.value( name ), name );
194194 return t;
195195 }
196196 throw Grantlee::Exception( TagSyntaxError, QString( "Couldn't load template %1. Template does not exist." ).arg( name ) );
  
5151 /**
5252 Load a MutableTemplate called @p name. Return an invalid Template if no content by that name exists.
5353 */
54 virtual MutableTemplate loadMutableByName( const QString &name ) const = 0;
54 virtual MutableTemplate loadMutableByName( const QString &name, Engine const *engine ) const = 0;
5555
5656 /**
5757 Load a Template called @p name. Return an invalid Template if no content by that name exists.
5858 */
59 virtual Template loadByName( const QString &name ) const = 0;
59 virtual Template loadByName( const QString &name, Engine const *engine ) const = 0;
6060
6161 /**
6262 Return a complete URI for media identified by fileName.
126126 */
127127 virtual ~FileSystemTemplateLoader();
128128
129 /* reimp */ MutableTemplate loadMutableByName( const QString &name ) const;
129 /* reimp */ MutableTemplate loadMutableByName( const QString &name, Engine const *engine ) const;
130130
131 /* reimp */ Template loadByName( const QString &name ) const;
131 /* reimp */ Template loadByName( const QString &name, Engine const *engine ) const;
132132
133133 /* reimp */ bool canLoadTemplate( const QString &name ) const;
134134
158158 InMemoryTemplateLoader();
159159 virtual ~InMemoryTemplateLoader();
160160
161 /* reimp */ MutableTemplate loadMutableByName( const QString &name ) const;
161 /* reimp */ MutableTemplate loadMutableByName( const QString &name, Engine const *engine ) const;
162162
163 /* reimp */ Template loadByName( const QString &name ) const;
163 /* reimp */ Template loadByName( const QString &name, Engine const *engine ) const;
164164
165165 /* reimp */ bool canLoadTemplate( const QString &name ) const;
166166
  
5252
5353QString MediaFinderNode::render( Context* c )
5454{
55 Grantlee::Engine *engine = Grantlee::Engine::instance();
5655 foreach( const FilterExpression &fe, m_mediaExpressionList ) {
5756 if ( fe.isTrue( c ) ) {
5857 TemplateImpl *ti = containerTemplate();
5958
60 return engine->mediaUri( Util::getSafeString( fe.resolve( c ) ), ti->state() );
59 return ti->engine()->mediaUri( Util::getSafeString( fe.resolve( c ) ) );
6160 }
6261 }
6362 return QString();
  
7878
7979 if ( m_parse ) {
8080 TemplateImpl *ti = containerTemplate();
81 Template t = Engine::instance()->newTemplate( content, m_filename, ti->state() );
81 Template t = ti->engine()->newTemplate( content, m_filename );
8282 return t->render( c );
8383 }
8484 return content;
  
110110 } else {
111111 parentName = m_name;
112112 }
113 Engine *engine = Engine::instance();
114113
115114 TemplateImpl *ti = containerTemplate();
116115
117 Template t = engine->loadByName( parentName, ti->state() );
116 Template t = ti->engine()->loadByName( parentName );
118117
119118 return t;
120119}
  
6161{
6262 QString filename = Util::getSafeString( m_filterExpression.resolve( c ) );
6363
64 Engine *engine = Engine::instance();
65
6664 TemplateImpl *ti = containerTemplate();
65
6766 try {
68 Template t = engine->loadByName( filename, ti->state() );
67 Template t = ti->engine()->loadByName( filename );
6968
7069 if ( !t )
7170 return QString();
8484
8585QString ConstantIncludeNode::render( Context *c )
8686{
87 Engine *engine = Engine::instance();
88
8987 TemplateImpl *ti = containerTemplate();
9088
9189 try {
92 Template t = engine->loadByName( m_name, ti->state() );
90 Template t = ti->engine()->loadByName( m_name );
9391 if ( !t )
9492 return QString();
9593
  
3535#include "token.h"
3636
3737Q_DECLARE_METATYPE( Token )
38Q_DECLARE_METATYPE( Engine* )
3839
3940QScriptValue tokenToScriptValue( QScriptEngine *engine, const Token &t )
4041{
9494 QScriptValue markSafeFunctionObject = m_scriptEngine->newFunction( markSafeFunction );
9595 m_scriptEngine->globalObject().setProperty( "mark_safe", markSafeFunctionObject );
9696
97}
98
99void ScriptableTagLibrary::setEngine( Engine *engine )
100{
101 m_scriptEngine->setProperty( "templateEngine", QVariant::fromValue( engine ) );
97102}
98103
99104bool ScriptableTagLibrary::evaluateScript( const QString &name )
  
3232
3333namespace Grantlee
3434{
35class Engine;
3536class Parser;
3637}
3738
4848 virtual QHash<QString, AbstractNodeFactory*> nodeFactories( const QString &name = QString() );
4949
5050 virtual QHash<QString, Filter*> filters( const QString &name = QString() );
51
52 /* reimp */ void setEngine( Grantlee::Engine *engine );
5153
5254public slots:
5355 void addFactory( const QString &factoryName, const QString &tagname );
  
2727#include "node.h"
2828#include "scriptablecontext.h"
2929
30Q_DECLARE_METATYPE( Engine* )
3031
32
3133QScriptValue ScriptableTemplateConstructor( QScriptContext *context,
3234 QScriptEngine *engine )
3335{
3436 QString content = context->argument( 0 ).toString();
3537 QString name = context->argument( 1 ).toString();
3638 QObject *parent = context->argument( 2 ).toQObject();
39 Engine *templateEngine = engine->property("templateEngine").value<Engine *>();
3740
38 Template t = Engine::instance()->newTemplate( content, name );
41 if ( !templateEngine )
42 return QScriptValue();
43
44 Template t = templateEngine->newTemplate( content, name );
3945
4046 ScriptableTemplate *object = new ScriptableTemplate( t, parent );
4147 return engine->newQObject( object );
  
134134private:
135135 Engine *m_engine;
136136
137 Engine* getEngine();
138
137139 void doTest();
138140
139141};
140142
141143void TestBuiltinSyntax::initTestCase()
142144{
143 m_engine = Engine::instance();
144 m_engine->setPluginDirs( QStringList() << GRANTLEE_PLUGIN_PATH );
145 m_engine = getEngine();
145146}
146147
148Engine* TestBuiltinSyntax::getEngine()
149{
150 Engine *engine = new Engine( this );
151 engine->setPluginDirs( QStringList() << GRANTLEE_PLUGIN_PATH );
152 return engine;
153}
154
147155void TestBuiltinSyntax::cleanupTestCase()
148156{
149157 delete m_engine;
164164 QFETCH( QString, output );
165165 QFETCH( Grantlee::Error, error );
166166
167 Template t = Engine::instance()->newTemplate( input, QTest::currentDataTag() );
167 Template t = m_engine->newTemplate( input, QTest::currentDataTag() );
168168
169169 Context context( dict );
170170
575575
576576void TestBuiltinSyntax::testMultipleStates()
577577{
578 Engine *engine = Engine::instance();
578 Engine *engine1 = getEngine();
579579
580580 InMemoryTemplateLoader::Ptr loader1 = InMemoryTemplateLoader::Ptr( new InMemoryTemplateLoader() );
581581
582582 loader1->setTemplate( "template1", "Template 1" );
583 engine->addTemplateLoader( loader1 );
583 engine1->addTemplateLoader( loader1 );
584584
585 Template t1 = engine->newTemplate( "{% include \"template1\" %}", "\"template1\"" );
585 Template t1 = engine1->newTemplate( "{% include \"template1\" %}", "\"template1\"" );
586586
587 Engine *engine2 = getEngine();
588
587589 InMemoryTemplateLoader::Ptr loader2 = InMemoryTemplateLoader::Ptr( new InMemoryTemplateLoader() );
588590
589591 loader2->setTemplate( "template2", "Template 2" );
590592
591 engine->addTemplateLoader( loader2 );
593 engine2->addTemplateLoader( loader2 );
592594
593 Template t2 = engine->newTemplate( "{% include \"template2\" %}", "\"template2\"" );
595 Template t2 = engine2->newTemplate( "{% include \"template2\" %}", "\"template2\"" );
594596
597 Engine *engine3 = getEngine();
598
595599 InMemoryTemplateLoader::Ptr loader3 = InMemoryTemplateLoader::Ptr( new InMemoryTemplateLoader() );
596600
597601 loader3->setTemplate( "template3", "Template 3" );
598602
599 engine->addTemplateLoader( loader3 );
603 engine3->addTemplateLoader( loader3 );
600604
601 Template t3 = engine->newTemplate( "{% include var %}", "var" );
605 Template t3 = engine3->newTemplate( "{% include var %}", "var" );
602606
603 // Cause Engine to change to a new state.
604 Template t4 = engine->newTemplate( "", "Dummy template" );
605
606607 QVariantHash h;
607608 h.insert( "var", "template3" );
608609 Context c( h );
610 t1->render( &c );
609611
610612 QString expected1 = "Template 1";
611613 QString expected2 = "Template 2";
615615 QCOMPARE( t1->render( &c ), expected1 );
616616 QCOMPARE( t2->render( &c ), expected2 );
617617 QCOMPARE( t3->render( &c ), expected3 );
618
619618}
620619
621620void TestBuiltinSyntax::testTemplatePathSafety_data()
641641 f.write( inputPath.toUtf8() );
642642 f.close();
643643
644 Template t = loader->loadByName( inputPath );
644 Template t = loader->loadByName( inputPath, m_engine );
645645 Context c;
646646 if ( output.isEmpty() )
647647 QVERIFY( !t );
648648 else
649649 QCOMPARE( t->render( &c ), inputPath );
650650
651 MutableTemplate mt = loader->loadMutableByName( inputPath );
651 MutableTemplate mt = loader->loadMutableByName( inputPath, m_engine );
652652 if ( output.isEmpty() )
653653 QVERIFY( !mt );
654654 else
  
134134
135135void TestDefaultTags::initTestCase()
136136{
137 m_engine = Engine::instance();
137 m_engine = new Engine( this );
138138 m_engine->setPluginDirs( QStringList() << GRANTLEE_PLUGIN_PATH );
139139}
140140
150150 QFETCH( QString, output );
151151 QFETCH( Grantlee::Error, error );
152152
153 Template t = Engine::instance()->newTemplate( input, QTest::currentDataTag() );
153 Template t = m_engine->newTemplate( input, QTest::currentDataTag() );
154154
155155 Context context( dict );
156156
  
8787
8888void TestFilters::initTestCase()
8989{
90 m_engine = Engine::instance();
90 m_engine = new Engine( this );
9191
9292 loader = InMemoryTemplateLoader::Ptr( new InMemoryTemplateLoader() );
9393 m_engine->addTemplateLoader( loader );
110110 QFETCH( QString, output );
111111 QFETCH( Grantlee::Error, errorNumber );
112112
113 Template t = Engine::instance()->newTemplate( input, QTest::currentDataTag() );
113 Template t = m_engine->newTemplate( input, QTest::currentDataTag() );
114114
115115 Context context( dict );
116116
  
6565
6666void TestLoaderTags::initTestCase()
6767{
68 m_engine = Engine::instance();
68 m_engine = new Engine( this );
6969
7070 loader = InMemoryTemplateLoader::Ptr( new InMemoryTemplateLoader() );
7171 m_engine->addTemplateLoader( loader );
8888 QFETCH( QString, output );
8989 QFETCH( Grantlee::Error, errorNumber );
9090
91 Template t = Engine::instance()->newTemplate( input, QTest::currentDataTag() );
91 Template t = m_engine->newTemplate( input, QTest::currentDataTag() );
9292
9393 Context context( dict );
9494
256256
257257 // Inheritance from local context without use of template loader
258258
259 Template t = Engine::instance()->newTemplate( "1{% block first %}_{% endblock %}3{% block second %}_{% endblock %}", "context_template" );
259 Template t = m_engine->newTemplate( "1{% block first %}_{% endblock %}3{% block second %}_{% endblock %}", "context_template" );
260260 dict.insert( "context_template", QVariant::fromValue( t ) );
261261
262262 QTest::newRow( "inheritance24" ) << "{% extends context_template %}{% block first %}2{% endblock %}{% block second %}4{% endblock %}" << dict << "1234" << NoError;
264264 dict.clear();
265265 QVariantList list;
266266
267 Template t1 = Engine::instance()->newTemplate( "Wrong", "context_template_1" );
268 Template t2 = Engine::instance()->newTemplate( "1{% block first %}_{% endblock %}3{% block second %}_{% endblock %}", "context_template_2" );
267 Template t1 = m_engine->newTemplate( "Wrong", "context_template_1" );
268 Template t2 = m_engine->newTemplate( "1{% block first %}_{% endblock %}3{% block second %}_{% endblock %}", "context_template_2" );
269269 list << QVariant::fromValue( t1 );
270270 list << QVariant::fromValue( t2 );
271271
  
5959
6060void TestMutableTagsSyntax::initTestCase()
6161{
62 m_engine = Engine::instance();
62 m_engine = new Engine( this );
6363 m_engine->setPluginDirs( QStringList() << GRANTLEE_PLUGIN_PATH );
6464
6565 m_engine->addDefaultLibrary( "grantlee_mutabletags" );
8181 QString content = "Begin"
8282 "{% raw %} Stuff {% endraw %}"
8383 "Afters.";
84 Template t = Engine::instance()->newMutableTemplate( content, "t1" );
84 Template t = m_engine->newMutableTemplate( content, "t1" );
8585
8686 Context c1( dict );
8787 QString result = t->render( &c1 );
110110 QString content = "Begin {% for name in nameList %}{{ name }},{% endfor %}"
111111 "{% raw %}{% for name in nameList %}{{ name }},{% endfor %} var: {{ var }}. {% endraw %}"
112112 "Afters.";
113 Template t = Engine::instance()->newMutableTemplate( content, "t" );
113 Template t = m_engine->newMutableTemplate( content, "t" );
114114
115115 Context c1( dict );
116116 QString result = t->render( &c1 );
148148 "{% repeater %}{% for name in nameList %}{{ name }},{% endfor %} var: {{ var }}. {% endrepeater %}"
149149 "Afters";
150150
151 Template t = Engine::instance()->newMutableTemplate( content, "t" );
151 Template t = m_engine->newMutableTemplate( content, "t" );
152152
153153 Context c1( dict );
154154 QString result = t->render( &c1 );
196196 "{% endrepeater %}"
197197 "After.";
198198
199 Template t = Engine::instance()->newMutableTemplate( content, "t" );
199 Template t = m_engine->newMutableTemplate( content, "t" );
200200
201201 QVariantHash h;
202202 Context c( h );
213213 "Bar."
214214 "{% endrepeater %}"
215215 "After.";
216 Template t2 = Engine::instance()->newMutableTemplate( content, "t2" );
216 Template t2 = m_engine->newMutableTemplate( content, "t2" );
217217
218218 h.insert( "var", "String" );
219219 Context c2( h );
  
6060
6161void TestScriptableTagsSyntax::initTestCase()
6262{
63 m_engine = Engine::instance();
63 m_engine = new Engine( this );
6464 QString appDirPath = QFileInfo( QCoreApplication::applicationDirPath() ).absoluteDir().path();
6565 m_engine->setPluginDirs( QStringList() << GRANTLEE_PLUGIN_PATH
6666 << ":/grantlee/" // For scripteddefaults.qs
7979 QFETCH( QString, output );
8080 QFETCH( Grantlee::Error, error );
8181
82 Template t = Engine::instance()->newTemplate( input, QTest::currentDataTag() );
82 Template t = m_engine->newTemplate( input, QTest::currentDataTag() );
8383
8484 Context context( dict );
8585