• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

Kross

manager.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  * manager.cpp
00003  * This file is part of the KDE project
00004  * copyright (C)2004-2007 by Sebastian Sauer (mail@dipe.org)
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  * You should have received a copy of the GNU Library General Public License
00015  * along with this program; see the file COPYING.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  ***************************************************************************/
00019 
00020 #include "manager.h"
00021 #include "interpreter.h"
00022 #include "action.h"
00023 #include "actioncollection.h"
00024 
00025 #include <QtCore/QObject>
00026 #include <QtCore/QArgument>
00027 #include <QtCore/QFile>
00028 #include <QtCore/QRegExp>
00029 #include <QtCore/QFileInfo>
00030 #include <QtCore/QPointer>
00031 #include <QtCore/QLibrary>
00032 #include <QtCore/QCoreApplication>
00033 
00034 #include <kstandarddirs.h>
00035 #include <klocale.h>
00036 
00037 extern "C"
00038 {
00039     typedef QObject* (*def_module_func)();
00040 }
00041 
00042 using namespace Kross;
00043 
00044 namespace Kross {
00045 
00047     class Manager::Private
00048     {
00049         public:
00051             QHash< QString, InterpreterInfo* > interpreterinfos;
00052 
00054             QStringList interpreters;
00055 
00057             QHash< QString, QPointer<QObject> > modules;
00058 
00060             ActionCollection* collection;
00061     };
00062 
00063 }
00064 
00065 Q_GLOBAL_STATIC(Manager, _self)
00066 
00067 Manager& Manager::self()
00068 {
00069     return *_self();
00070 }
00071 
00072 void* loadLibrary(const char* libname, const char* functionname)
00073 {
00074     QLibrary lib(libname);
00075     lib.setLoadHints( QLibrary::ExportExternalSymbolsHint );
00076     if( ! lib.load() ) {
00077         const QString err = QString("Error: %1").arg(lib.errorString());
00078 
00079         //TODO move that functionality out of Kross since we like to be Qt-only
00080         foreach(const QString &dir, KStandardDirs().resourceDirs("module")) {
00081             lib.setFileName( QFileInfo(dir, libname).filePath() );
00082             lib.setLoadHints( QLibrary::ExportExternalSymbolsHint );
00083             if( lib.load() )
00084                 break;
00085         }
00086 
00087         /*
00088         if( ! lib.isLoaded() ) {
00089             foreach(QString path, QCoreApplication::instance()->libraryPaths()) {
00090                 lib.setFileName( QFileInfo(path, libname).filePath() );
00091                 lib.setLoadHints( QLibrary::ExportExternalSymbolsHint );
00092                 if( lib.load() )
00093                     break;
00094             }
00095         }
00096         */
00097 
00098         if( ! lib.isLoaded() ) {
00099             #ifdef KROSS_INTERPRETER_DEBUG
00100                 if( strcmp(functionname, "krossinterpreter") == 0 )
00101                     krossdebug( QString("Kross Interpreter '%1' not available: %2").arg(libname).arg(err) );
00102                 else if( strcmp(functionname, "krossmodule") == 0 )
00103                     krossdebug( QString("Kross Module '%1' not available: %2").arg(libname).arg(err) );
00104                 else
00105                     krosswarning( QString("Failed to load unknown type of '%1' library: %2").arg(libname).arg(err) );
00106             #endif
00107             return 0;
00108         }
00109     }
00110     void* funcPtr = lib.resolve(functionname);
00111     Q_ASSERT(funcPtr);
00112     return funcPtr;
00113 }
00114 
00115 Manager::Manager()
00116     : QObject()
00117     , QScriptable()
00118     , ChildrenInterface()
00119     , d( new Private() )
00120 {
00121     setObjectName("Kross");
00122     d->collection = new ActionCollection("main");
00123 
00124 #ifdef KROSS_PYTHON_LIBRARY
00125     if( void* funcPtr = loadLibrary(KROSS_PYTHON_LIBRARY, "krossinterpreter") ) {
00126         d->interpreterinfos.insert("python",
00127             new InterpreterInfo("python",
00128                 funcPtr, // library
00129                 "*.py", // file filter-wildcard
00130                 QStringList() << "text/x-python" // mimetypes
00131             )
00132         );
00133     }
00134 #endif
00135 
00136 #ifdef KROSS_RUBY_LIBRARY
00137     if( void* funcPtr = loadLibrary(KROSS_RUBY_LIBRARY, "krossinterpreter") ) {
00138         InterpreterInfo::Option::Map options;
00139         options.insert("safelevel", new InterpreterInfo::Option(
00140             i18n("Level of safety of the Ruby interpreter"),
00141             QVariant(0) )); // 0 -> unsafe, 4 -> very safe
00142         d->interpreterinfos.insert("ruby",
00143             new InterpreterInfo("ruby",
00144                 funcPtr, // library
00145                 "*.rb", // file filter-wildcard
00146                 QStringList() << /* "text/x-ruby" << */ "application/x-ruby", // mimetypes
00147                 options // options
00148             )
00149         );
00150     }
00151 #endif
00152 
00153 #ifdef KROSS_JAVA_LIBRARY
00154     if( void* funcPtr = loadLibrary(KROSS_JAVA_LIBRARY, "krossinterpreter") ) {
00155         d->interpreterinfos.insert("java",
00156             new InterpreterInfo("java",
00157                 funcPtr, // library
00158                 "*.java *.class *.jar", // file filter-wildcard
00159                 QStringList() << "application/java" // mimetypes
00160             )
00161         );
00162     }
00163 #endif
00164 
00165 #ifdef KROSS_KJS_LIBRARY
00166     if( void* funcPtr = loadLibrary(KROSS_KJS_LIBRARY, "krossinterpreter") ) {
00167         d->interpreterinfos.insert("javascript",
00168             new InterpreterInfo("javascript",
00169                 funcPtr, // library
00170                 "*.js", // file filter-wildcard
00171                 QStringList() << "application/javascript" // mimetypes
00172             )
00173         );
00174     }
00175 #endif
00176 
00177 #ifdef KROSS_FALCON_LIBRARY
00178     if( void* funcPtr = loadLibrary(KROSS_FALCON_LIBRARY, "krossinterpreter") ) {
00179         d->interpreterinfos.insert("falcon",
00180             new InterpreterInfo("falcon",
00181                 funcPtr, // library
00182                 "*.fal", // file filter-wildcard
00183                 QStringList() << "application/x-falcon" // mimetypes
00184             )
00185         );
00186     }
00187 #endif
00188 
00189 #ifdef KROSS_QTSCRIPT_LIBRARY
00190     if( void* funcPtr = loadLibrary(KROSS_QTSCRIPT_LIBRARY, "krossinterpreter") ) {
00191         d->interpreterinfos.insert("qtscript",
00192             new InterpreterInfo("qtscript",
00193                 funcPtr, // library
00194                 "*.es", // file filter-wildcard
00195                 QStringList() << "application/ecmascript" // mimetypes
00196             )
00197         );
00198     }
00199 #endif
00200 
00201     // fill the list of supported interpreternames.
00202     QHash<QString, InterpreterInfo*>::Iterator it( d->interpreterinfos.begin() );
00203     for(; it != d->interpreterinfos.end(); ++it)
00204         if( it.value() )
00205             d->interpreters << it.key();
00206     d->interpreters.sort();
00207 
00208     // publish ourself.
00209     ChildrenInterface::addObject(this, "Kross");
00210 }
00211 
00212 Manager::~Manager()
00213 {
00214     qDeleteAll(d->interpreterinfos.values());
00215     qDeleteAll(d->modules.values());
00216     delete d->collection;
00217     delete d;
00218 }
00219 
00220 QHash< QString, InterpreterInfo* > Manager::interpreterInfos() const
00221 {
00222     return d->interpreterinfos;
00223 }
00224 
00225 bool Manager::hasInterpreterInfo(const QString& interpretername) const
00226 {
00227     return d->interpreterinfos.contains(interpretername) && d->interpreterinfos[interpretername];
00228 }
00229 
00230 InterpreterInfo* Manager::interpreterInfo(const QString& interpretername) const
00231 {
00232     return hasInterpreterInfo(interpretername) ? d->interpreterinfos[interpretername] : 0;
00233 }
00234 
00235 const QString Manager::interpreternameForFile(const QString& file)
00236 {
00237     QRegExp rx;
00238     rx.setPatternSyntax(QRegExp::Wildcard);
00239     for(QHash<QString, InterpreterInfo*>::Iterator it = d->interpreterinfos.begin(); it != d->interpreterinfos.end(); ++it) {
00240         if( ! it.value() )
00241             continue;
00242         foreach(const QString &wildcard, it.value()->wildcard().split(" ", QString::SkipEmptyParts)) {
00243             rx.setPattern( wildcard );
00244             if( rx.exactMatch(file) )
00245                 return it.value()->interpreterName();
00246         }
00247     }
00248     return QString();
00249 }
00250 
00251 Interpreter* Manager::interpreter(const QString& interpretername) const
00252 {
00253     if( ! hasInterpreterInfo(interpretername) ) {
00254         krosswarning( QString("No such interpreter '%1'").arg(interpretername) );
00255         return 0;
00256     }
00257     return d->interpreterinfos[interpretername]->interpreter();
00258 }
00259 
00260 QStringList Manager::interpreters() const
00261 {
00262     return d->interpreters;
00263 }
00264 
00265 ActionCollection* Manager::actionCollection() const
00266 {
00267     return d->collection;
00268 }
00269 
00270 bool Manager::hasAction(const QString& name)
00271 {
00272     return findChild< Action* >(name) != 0L;
00273 }
00274 
00275 QObject* Manager::action(const QString& name)
00276 {
00277     Action* action = findChild< Action* >(name);
00278     if(! action) {
00279         action = new Action(this, name);
00280 #if 0
00281         d->actioncollection->insert(action); //FIXME should we really remember the action?
00282 #endif
00283     }
00284     return action;
00285 }
00286 
00287 QObject* Manager::module(const QString& modulename)
00288 {
00289     if( d->modules.contains(modulename) ) {
00290         QObject* obj = d->modules[modulename];
00291         if( obj )
00292             return obj;
00293     }
00294 
00295     if( modulename.isEmpty() || modulename.contains( QRegExp("[^a-zA-Z0-9]") ) ) {
00296         krosswarning( QString("Invalid module name '%1'").arg(modulename) );
00297         return 0;
00298     }
00299 
00300     QByteArray libraryname = QString("krossmodule%1").arg(modulename).toLower().toLatin1();
00301 
00302 #if 0
00303     KLibLoader* loader = KLibLoader::self();
00304     KLibrary* lib = loader->library( libraryname, QLibrary::ExportExternalSymbolsHint );
00305     if( ! lib ) { //FIXME this fallback-code should be in KLibLoader imho.
00306         lib = loader->library( QString("lib%1").arg(libraryname), QLibrary::ExportExternalSymbolsHint );
00307         if( ! lib ) {
00308             krosswarning( QString("Failed to load module '%1': %2").arg(modulename).arg(loader->lastErrorMessage()) );
00309             return 0;
00310         }
00311     }
00312 
00313     def_module_func func;
00314     func = (def_module_func) lib->resolveFunction("krossmodule");
00315     if( ! func ) {
00316         krosswarning( QString("Failed to determinate init function in module '%1'").arg(modulename) );
00317         return 0;
00318     }
00319 
00320     QObject* module = (QObject*) (func)(); // call the function
00321     lib->unload(); // unload the library
00322 
00323     if( ! module ) {
00324         krosswarning( QString("Failed to load module object '%1'").arg(modulename) );
00325         return 0;
00326     }
00327 #else
00328     if( void* funcPtr = loadLibrary(libraryname, "krossmodule") ) {
00329         def_module_func func = (def_module_func) funcPtr;
00330         Q_ASSERT( func );
00331         QObject* module = (QObject*) (func)(); // call the function
00332         Q_ASSERT( module );
00333         //krossdebug( QString("Manager::module Module successfully loaded: modulename=%1 module.objectName=%2 module.className=%3").arg(modulename).arg(module->objectName()).arg(module->metaObject()->className()) );
00334         d->modules.insert(modulename, module);
00335         return module;
00336     }
00337     else {
00338         krosswarning( QString("Failed to load module '%1'").arg(modulename) );
00339     }
00340 #endif
00341     return 0;
00342 }
00343 
00344 bool Manager::executeScriptFile(const QUrl& file)
00345 {
00346     krossdebug( QString("Manager::executeScriptFile() file='%1'").arg(file.toString()) );
00347     Action* action = new Action(0 /*no parent*/, file);
00348     action->trigger();
00349     bool ok = ! action->hadError();
00350     delete action; //action->delayedDestruct();
00351     return ok;
00352 }
00353 
00354 void Manager::addQObject(QObject* obj, const QString &name)
00355 {
00356     this->addObject(obj, name);
00357 }
00358 
00359 QObject* Manager::qobject(const QString &name) const
00360 {
00361     return this->object(name);
00362 }
00363 
00364 QStringList Manager::qobjectNames() const
00365 {
00366     return this->objects().keys();
00367 }
00368 
00369 #include "manager.moc"

Kross

Skip menu "Kross"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal