Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativetypeloader_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QDECLARATIVETYPELOADER_P_H
43 #define QDECLARATIVETYPELOADER_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists purely as an
50 // implementation detail.  This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include <QtCore/qobject.h>
57 #include <QtCore/qatomic.h>
58 #include <QtNetwork/qnetworkreply.h>
59 #include <QtDeclarative/qdeclarativeerror.h>
60 #include <QtDeclarative/qdeclarativeengine.h>
61
62 #include <private/qv8_p.h>
63 #include <private/qhashedstring_p.h>
64 #include <private/qdeclarativescript_p.h>
65 #include <private/qdeclarativeimport_p.h>
66 #include <private/qdeclarativecleanup_p.h>
67 #include <private/qdeclarativedirparser_p.h>
68
69 QT_BEGIN_NAMESPACE
70
71 class QDeclarativeScriptData;
72 class QDeclarativeScriptBlob;
73 class QDeclarativeQmldirData;
74 class QDeclarativeTypeLoader;
75 class QDeclarativeCompiledData;
76 class QDeclarativeComponentPrivate;
77 class QDeclarativeTypeData;
78 class QDeclarativeDataLoader;
79 class QDeclarativeExtensionInterface;
80
81 // Exported for QtQuick1
82 class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDataBlob : public QDeclarativeRefCount
83 {
84 public:
85     enum Status {
86         Null,                    // Prior to QDeclarativeDataLoader::load()
87         Loading,                 // Prior to data being received and dataReceived() being called
88         WaitingForDependencies,  // While there are outstanding addDependency()s
89         Complete,                // Finished
90         Error                    // Error
91     };
92
93     enum Type {
94         QmlFile,
95         JavaScriptFile,
96         QmldirFile
97     };
98
99     QDeclarativeDataBlob(const QUrl &, Type);
100     virtual ~QDeclarativeDataBlob();
101
102     Type type() const;
103
104     Status status() const;
105     bool isNull() const;
106     bool isLoading() const;
107     bool isWaiting() const;
108     bool isComplete() const;
109     bool isError() const;
110     bool isCompleteOrError() const;
111
112     qreal progress() const;
113
114     QUrl url() const;
115     QUrl finalUrl() const;
116
117     QList<QDeclarativeError> errors() const;
118
119 protected:
120     // Can be called from within callbacks
121     void setError(const QDeclarativeError &);
122     void setError(const QList<QDeclarativeError> &errors);
123     void addDependency(QDeclarativeDataBlob *);
124
125     // Callbacks made in load thread
126     virtual void dataReceived(const QByteArray &) = 0;
127     virtual void done();
128     virtual void networkError(QNetworkReply::NetworkError);
129     virtual void dependencyError(QDeclarativeDataBlob *);
130     virtual void dependencyComplete(QDeclarativeDataBlob *);
131     virtual void allDependenciesDone();
132
133     // Callbacks made in main thread
134     virtual void downloadProgressChanged(qreal);
135     virtual void completed();
136 private:
137     friend class QDeclarativeDataLoader;
138     friend class QDeclarativeDataLoaderThread;
139
140     void tryDone();
141     void cancelAllWaitingFor();
142     void notifyAllWaitingOnMe();
143     void notifyComplete(QDeclarativeDataBlob *);
144
145     struct ThreadData {
146         inline ThreadData();
147         inline QDeclarativeDataBlob::Status status() const;
148         inline void setStatus(QDeclarativeDataBlob::Status);
149         inline bool isAsync() const;
150         inline void setIsAsync(bool);
151         inline quint8 progress() const;
152         inline void setProgress(quint8);
153
154     private:
155         QAtomicInt _p;
156     };
157     ThreadData m_data;
158
159     // m_errors should *always* be written before the status is set to Error.
160     // We use the status change as a memory fence around m_errors so that locking
161     // isn't required.  Once the status is set to Error (or Complete), m_errors 
162     // cannot be changed.
163     QList<QDeclarativeError> m_errors;
164
165     Type m_type;
166
167     QUrl m_url;
168     QUrl m_finalUrl;
169
170     // List of QDeclarativeDataBlob's that are waiting for me to complete.
171     QList<QDeclarativeDataBlob *> m_waitingOnMe;
172
173     // List of QDeclarativeDataBlob's that I am waiting for to complete.
174     QList<QDeclarativeDataBlob *> m_waitingFor;
175
176     // Manager that is currently fetching data for me
177     QDeclarativeDataLoader *m_manager;
178     int m_redirectCount:30;
179     bool m_inCallback:1;
180     bool m_isDone:1;
181 };
182
183 class QDeclarativeDataLoaderThread;
184 // Exported for QtQuick1
185 class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDataLoader 
186 {
187 public:
188     QDeclarativeDataLoader(QDeclarativeEngine *);
189     ~QDeclarativeDataLoader();
190
191     void lock();
192     void unlock();
193
194     bool isConcurrent() const { return true; }
195
196     enum Mode { PreferSynchronous, Asynchronous };
197
198     void load(QDeclarativeDataBlob *, Mode = PreferSynchronous);
199     void loadWithStaticData(QDeclarativeDataBlob *, const QByteArray &, Mode = PreferSynchronous);
200
201     QDeclarativeEngine *engine() const;
202     void initializeEngine(QDeclarativeExtensionInterface *, const char *);
203
204 private:
205     friend class QDeclarativeDataBlob;
206     friend class QDeclarativeDataLoaderThread;
207     friend class QDeclarativeDataLoaderNetworkReplyProxy;
208
209     void loadThread(QDeclarativeDataBlob *);
210     void loadWithStaticDataThread(QDeclarativeDataBlob *, const QByteArray &);
211     void networkReplyFinished(QNetworkReply *);
212     void networkReplyProgress(QNetworkReply *, qint64, qint64);
213     
214     typedef QHash<QNetworkReply *, QDeclarativeDataBlob *> NetworkReplies;
215
216     void setData(QDeclarativeDataBlob *, const QByteArray &);
217
218     QDeclarativeEngine *m_engine;
219     QDeclarativeDataLoaderThread *m_thread;
220     NetworkReplies m_networkReplies;
221 };
222
223 // Exported for QtQuick1
224 class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeTypeLoader : public QDeclarativeDataLoader
225 {
226     Q_DECLARE_TR_FUNCTIONS(QDeclarativeTypeLoader)
227 public:
228     QDeclarativeTypeLoader(QDeclarativeEngine *);
229     ~QDeclarativeTypeLoader();
230
231     enum Option {
232         None,
233         PreserveParser
234     };
235     Q_DECLARE_FLAGS(Options, Option)
236
237     QDeclarativeTypeData *get(const QUrl &url);
238     QDeclarativeTypeData *get(const QByteArray &, const QUrl &url, Options = None);
239     void clearCache();
240
241     QDeclarativeScriptBlob *getScript(const QUrl &);
242     QDeclarativeQmldirData *getQmldir(const QUrl &);
243
244     QString absoluteFilePath(const QString &path);
245     bool directoryExists(const QString &path);
246     const QDeclarativeDirParser *qmlDirParser(const QString &absoluteFilePath);
247 private:
248     typedef QHash<QUrl, QDeclarativeTypeData *> TypeCache;
249     typedef QHash<QUrl, QDeclarativeScriptBlob *> ScriptCache;
250     typedef QHash<QUrl, QDeclarativeQmldirData *> QmldirCache;
251     typedef QStringHash<bool> StringSet;
252     typedef QStringHash<StringSet*> ImportDirCache;
253     typedef QStringHash<QDeclarativeDirParser*> ImportQmlDirCache;
254
255     TypeCache m_typeCache;
256     ScriptCache m_scriptCache;
257     QmldirCache m_qmldirCache;
258     ImportDirCache m_importDirCache;
259     ImportQmlDirCache m_importQmlDirCache;
260 };
261
262 Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeTypeLoader::Options)
263
264 class Q_AUTOTEST_EXPORT QDeclarativeTypeData : public QDeclarativeDataBlob
265 {
266 public:
267     struct TypeReference
268     {
269         TypeReference() : type(0), majorVersion(0), minorVersion(0), typeData(0) {}
270
271         QDeclarativeScript::Location location;
272         QDeclarativeType *type;
273         int majorVersion;
274         int minorVersion;
275         QDeclarativeTypeData *typeData;
276     };
277
278     struct ScriptReference
279     {
280         ScriptReference() : script(0) {}
281
282         QDeclarativeScript::Location location;
283         QString qualifier;
284         QDeclarativeScriptBlob *script;
285     };
286
287     QDeclarativeTypeData(const QUrl &, QDeclarativeTypeLoader::Options, QDeclarativeTypeLoader *);
288     ~QDeclarativeTypeData();
289
290     QDeclarativeTypeLoader *typeLoader() const;
291
292     const QDeclarativeImports &imports() const;
293     const QDeclarativeScript::Parser &parser() const;
294
295     const QList<TypeReference> &resolvedTypes() const;
296     const QList<ScriptReference> &resolvedScripts() const;
297     const QSet<QString> &namespaces() const;
298
299     QDeclarativeCompiledData *compiledData() const;
300
301     // Used by QDeclarativeComponent to get notifications
302     struct TypeDataCallback {
303         ~TypeDataCallback() {}
304         virtual void typeDataProgress(QDeclarativeTypeData *, qreal) {}
305         virtual void typeDataReady(QDeclarativeTypeData *) {}
306     };
307     void registerCallback(TypeDataCallback *);
308     void unregisterCallback(TypeDataCallback *);
309
310 protected:
311     virtual void done();
312     virtual void completed();
313     virtual void dataReceived(const QByteArray &);
314     virtual void allDependenciesDone();
315     virtual void downloadProgressChanged(qreal);
316
317 private:
318     void resolveTypes();
319     void compile();
320
321     QDeclarativeTypeLoader::Options m_options;
322
323     QDeclarativeQmldirData *qmldirForUrl(const QUrl &);
324
325     QDeclarativeScript::Parser scriptParser;
326     QDeclarativeImports m_imports;
327
328     QList<ScriptReference> m_scripts;
329     QList<QDeclarativeQmldirData *> m_qmldirs;
330
331     QSet<QString> m_namespaces;
332
333     QList<TypeReference> m_types;
334     bool m_typesResolved:1;
335
336     QDeclarativeCompiledData *m_compiledData;
337
338     QList<TypeDataCallback *> m_callbacks;
339    
340     QDeclarativeTypeLoader *m_typeLoader;
341 };
342
343 // QDeclarativeScriptData instances are created, uninitialized, by the loader in the 
344 // load thread.  The first time they are used by the VME, they are initialized which
345 // creates their v8 objects and they are referenced and added to the  engine's cleanup
346 // list.  During QDeclarativeCleanup::clear() all v8 resources are destroyed, and the 
347 // reference that was created is released but final deletion only occurs once all the
348 // references as released.  This is all intended to ensure that the v8 resources are
349 // only created and destroyed in the main thread :)
350 class Q_AUTOTEST_EXPORT QDeclarativeScriptData : public QDeclarativeCleanup, 
351                                                  public QDeclarativeRefCount
352 {
353 public:
354     QDeclarativeScriptData();
355     ~QDeclarativeScriptData();
356
357     QUrl url;
358     QDeclarativeTypeNameCache *importCache;
359     QList<QDeclarativeScriptBlob *> scripts;
360     QDeclarativeScript::Object::ScriptBlock::Pragmas pragmas;
361
362     bool isInitialized() const { return hasEngine(); }
363     void initialize(QDeclarativeEngine *);
364
365 protected:
366     virtual void clear(); // From QDeclarativeCleanup
367
368 private:
369     friend class QDeclarativeVME;
370     friend class QDeclarativeScriptBlob;
371
372     bool m_loaded;
373     QString m_programSource;
374     v8::Persistent<v8::Script> m_program;
375     v8::Persistent<v8::Object> m_value;
376 };
377
378 class Q_AUTOTEST_EXPORT QDeclarativeScriptBlob : public QDeclarativeDataBlob
379 {
380 public:
381     QDeclarativeScriptBlob(const QUrl &, QDeclarativeTypeLoader *);
382     ~QDeclarativeScriptBlob();
383
384     struct ScriptReference
385     {
386         ScriptReference() : script(0) {}
387
388         QDeclarativeScript::Location location;
389         QString qualifier;
390         QDeclarativeScriptBlob *script;
391     };
392
393     QDeclarativeScript::Object::ScriptBlock::Pragmas pragmas() const;
394     QString scriptSource() const;
395
396     QDeclarativeTypeLoader *typeLoader() const;
397     const QDeclarativeImports &imports() const;
398
399     QDeclarativeScriptData *scriptData() const;
400
401 protected:
402     virtual void dataReceived(const QByteArray &);
403     virtual void done();
404
405 private:
406     QDeclarativeScript::Object::ScriptBlock::Pragmas m_pragmas;
407     QString m_source;
408
409     QDeclarativeImports m_imports;
410     QList<ScriptReference> m_scripts;
411     QDeclarativeScriptData *m_scriptData;
412
413     QDeclarativeTypeLoader *m_typeLoader;
414 };
415
416 class Q_AUTOTEST_EXPORT QDeclarativeQmldirData : public QDeclarativeDataBlob
417 {
418 public:
419     QDeclarativeQmldirData(const QUrl &);
420
421     const QDeclarativeDirComponents &dirComponents() const;
422
423 protected:
424     virtual void dataReceived(const QByteArray &);
425
426 private:
427     QDeclarativeDirComponents m_components;
428
429 };
430
431 QT_END_NAMESPACE
432
433 #endif // QDECLARATIVETYPELOADER_P_H