~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/corelib/plugin/qfactoryloader.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the core module of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "qfactoryloader_p.h"
 
30
#include "qfactoryinterface.h"
 
31
#include "qmap.h"
 
32
#include <qdir.h>
 
33
#include <qsettings.h>
 
34
#include <qdebug.h>
 
35
#include "qmutex.h"
 
36
#include "qplugin.h"
 
37
#include "qpluginloader.h"
 
38
#include "private/qobject_p.h"
 
39
#include "private/qcoreapplication_p.h"
 
40
 
 
41
class QFactoryLoaderPrivate : public QObjectPrivate
 
42
{
 
43
    Q_DECLARE_PUBLIC(QFactoryLoader)
 
44
public:
 
45
    QFactoryLoaderPrivate(){}
 
46
    mutable QMutex mutex;
 
47
    QByteArray iid;
 
48
    QList<QLibraryPrivate*> libraryList;
 
49
    QMap<QString,QLibraryPrivate*> keyMap;
 
50
    QStringList keyList;
 
51
};
 
52
 
 
53
QFactoryLoader::QFactoryLoader(const char *iid,
 
54
                               const QStringList &paths, const QString &suffix,
 
55
                               Qt::CaseSensitivity cs)
 
56
    : QObject(*new QFactoryLoaderPrivate)
 
57
{
 
58
    QCoreApplicationPrivate::moveToMainThread(this);
 
59
    Q_D(QFactoryLoader);
 
60
    d->iid = iid;
 
61
 
 
62
    QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
 
63
 
 
64
    for (int i = 0; i < paths.count(); ++i) {
 
65
        QString path = paths.at(i) + suffix;
 
66
        if (!QDir(path).exists(QLatin1String(".")))
 
67
            continue;
 
68
        QStringList plugins = QDir(path).entryList(QDir::Files);
 
69
        QLibraryPrivate *library = 0;
 
70
        for (int j = 0; j < plugins.count(); ++j) {
 
71
            QString fileName = QDir::cleanPath(path + QLatin1Char('/') + plugins.at(j));
 
72
            library = QLibraryPrivate::findOrCreate(QFileInfo(fileName).canonicalFilePath());
 
73
            if (!library->isPlugin()) {
 
74
                library->release();
 
75
                continue;
 
76
            }
 
77
            QString regkey = QString::fromLatin1("Qt Factory Cache %1.%2/%3:/%4")
 
78
                             .arg((QT_VERSION & 0xff0000) >> 16)
 
79
                             .arg((QT_VERSION & 0xff00) >> 8)
 
80
                             .arg(QLatin1String(iid))
 
81
                             .arg(fileName);
 
82
            QStringList reg, keys;
 
83
            reg = settings.value(regkey).toStringList();
 
84
            if (reg.count() && library->lastModified == reg[0]) {
 
85
                keys = reg;
 
86
                keys.removeFirst();
 
87
            } else {
 
88
                if (!library->loadPlugin()) {
 
89
                    library->release();
 
90
                    continue;
 
91
                }
 
92
                QObject *instance = library->instance();
 
93
                QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instance);
 
94
                if (instance && factory && instance->qt_metacast(iid))
 
95
                    keys = factory->keys();
 
96
                if (keys.isEmpty())
 
97
                    library->unload();
 
98
                reg.clear();
 
99
                reg << library->lastModified;
 
100
                reg += keys;
 
101
                settings.setValue(regkey, reg);
 
102
            }
 
103
            if (keys.isEmpty()) {
 
104
                library->release();
 
105
                continue;
 
106
            }
 
107
            d->libraryList += library;
 
108
            for (int k = 0; k < keys.count(); ++k) {
 
109
                // first come first serve, unless the first
 
110
                // library was built with a future Qt version,
 
111
                // whereas the new one has a Qt version that fits
 
112
                // better
 
113
                QString key = keys.at(k);
 
114
                if (!cs)
 
115
                    key = key.toLower();
 
116
                QLibraryPrivate *previous = d->keyMap.value(key);
 
117
                if (!previous || (previous->qt_version > QT_VERSION && library->qt_version <= QT_VERSION)) {
 
118
                    d->keyMap[key] = library;
 
119
                    d->keyList += keys.at(k);
 
120
                }
 
121
            }
 
122
        }
 
123
    }
 
124
}
 
125
 
 
126
QFactoryLoader::~QFactoryLoader()
 
127
{
 
128
    Q_D(QFactoryLoader);
 
129
    for (int i = 0; i < d->libraryList.count(); ++i)
 
130
        d->libraryList.at(i)->release();
 
131
}
 
132
 
 
133
QStringList QFactoryLoader::keys() const
 
134
{
 
135
    Q_D(const QFactoryLoader);
 
136
    QMutexLocker locker(&d->mutex);
 
137
    QStringList keys = d->keyList;
 
138
    QObjectList instances = QPluginLoader::staticInstances();
 
139
    for (int i = 0; i < instances.count(); ++i)
 
140
        if (QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instances.at(i)))
 
141
            if (instances.at(i)->qt_metacast(d->iid))
 
142
                    keys += factory->keys();
 
143
    return keys;
 
144
}
 
145
 
 
146
QObject *QFactoryLoader::instance(const QString &key) const
 
147
{
 
148
    Q_D(const QFactoryLoader);
 
149
    QMutexLocker locker(&d->mutex);
 
150
    QObjectList instances = QPluginLoader::staticInstances();
 
151
    for (int i = 0; i < instances.count(); ++i)
 
152
        if (QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instances.at(i)))
 
153
            if (instances.at(i)->qt_metacast(d->iid) && factory->keys().contains(key, Qt::CaseInsensitive))
 
154
                return instances.at(i);
 
155
 
 
156
    if (QLibraryPrivate* library = d->keyMap.value(key)) {
 
157
        if (library->instance || library->loadPlugin()) {
 
158
            if (QObject *obj = library->instance()) {
 
159
                if (obj && !obj->parent())
 
160
                    QCoreApplicationPrivate::moveToMainThread(obj);
 
161
                return obj;
 
162
            }
 
163
        }
 
164
    }
 
165
    return 0;
 
166
}