• Skip to content
  • Skip to link menu
KDE 4.3 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 
00063             QHash<QByteArray, MetaTypeHandler*> wrappers;
00064 
00066             bool strictTypesEnabled;
00067     };
00068 
00069 }
00070 
00071 Q_GLOBAL_STATIC(Manager, _self)
00072 
00073 Manager& Manager::self()
00074 {
00075     return *_self();
00076 }
00077 
00078 void* loadLibrary(const char* libname, const char* functionname)
00079 {
00080     QLibrary lib(libname);
00081     lib.setLoadHints( QLibrary::ExportExternalSymbolsHint );
00082     if( ! lib.load() ) {
00083         const QString err = QString("Error: %1").arg(lib.errorString());
00084 
00085         //TODO move that functionality out of Kross since we like to be Qt-only
00086         foreach(const QString &dir, KStandardDirs().resourceDirs("module")) {
00087             lib.setFileName( QFileInfo(dir, libname).filePath() );
00088             lib.setLoadHints( QLibrary::ExportExternalSymbolsHint );
00089             if( lib.load() )
00090                 break;
00091         }
00092 
00093         /*
00094         if( ! lib.isLoaded() ) {
00095             foreach(const QString& path, QCoreApplication::instance()->libraryPaths()) {
00096                 lib.setFileName( QFileInfo(path, libname).filePath() );
00097                 lib.setLoadHints( QLibrary::ExportExternalSymbolsHint );
00098                 if( lib.load() )
00099                     break;
00100             }
00101         }
00102         */
00103 
00104         if( ! lib.isLoaded() ) {
00105             #ifdef KROSS_INTERPRETER_DEBUG
00106                 if( strcmp(functionname, "krossinterpreter") == 0 )
00107                     krossdebug( QString("Kross Interpreter '%1' not available: %2").arg(libname).arg(err) );
00108                 else if( strcmp(functionname, "krossmodule") == 0 )
00109                     krossdebug( QString("Kross Module '%1' not available: %2").arg(libname).arg(err) );
00110                 else
00111                     krosswarning( QString("Failed to load unknown type of '%1' library: %2").arg(libname).arg(err) );
00112             #endif
00113             return 0;
00114         }
00115     }
00116     void* funcPtr = lib.resolve(functionname);
00117     Q_ASSERT(funcPtr);
00118     return funcPtr;
00119 }
00120 
00121 Manager::Manager()
00122     : QObject()
00123     , QScriptable()
00124     , ChildrenInterface()
00125     , d( new Private() )
00126 {
00127     d->strictTypesEnabled = true;
00128     setObjectName("Kross");
00129     d->collection = new ActionCollection("main");
00130 
00131 #ifdef KROSS_PYTHON_LIBRARY
00132     if( void* funcPtr = loadLibrary(KROSS_PYTHON_LIBRARY, "krossinterpreter") ) {
00133         d->interpreterinfos.insert("python",
00134             new InterpreterInfo("python",
00135                 funcPtr, // library
00136                 "*.py", // file filter-wildcard
00137                 QStringList() << "text/x-python" // mimetypes
00138             )
00139         );
00140     }
00141 #endif
00142 
00143 #ifdef KROSS_RUBY_LIBRARY
00144     if( void* funcPtr = loadLibrary(KROSS_RUBY_LIBRARY, "krossinterpreter") ) {
00145         InterpreterInfo::Option::Map options;
00146         options.insert("safelevel", new InterpreterInfo::Option(
00147             i18n("Level of safety of the Ruby interpreter"),
00148             QVariant(0) )); // 0 -> unsafe, 4 -> very safe
00149         d->interpreterinfos.insert("ruby",
00150             new InterpreterInfo("ruby",
00151                 funcPtr, // library
00152                 "*.rb", // file filter-wildcard
00153                 QStringList() << /* "text/x-ruby" << */ "application/x-ruby", // mimetypes
00154                 options // options
00155             )
00156         );
00157     }
00158 #endif
00159 
00160 #ifdef KROSS_JAVA_LIBRARY
00161     if( void* funcPtr = loadLibrary(KROSS_JAVA_LIBRARY, "krossinterpreter") ) {
00162         d->interpreterinfos.insert("java",
00163             new InterpreterInfo("java",
00164                 funcPtr, // library
00165                 "*.java *.class *.jar", // file filter-wildcard
00166                 QStringList() << "application/java" // mimetypes
00167             )
00168         );
00169     }
00170 #endif
00171 
00172 #ifdef KROSS_KJS_LIBRARY
00173     if( void* funcPtr = loadLibrary(KROSS_KJS_LIBRARY, "krossinterpreter") ) {
00174         d->interpreterinfos.insert("javascript",
00175             new InterpreterInfo("javascript",
00176                 funcPtr, // library
00177                 "*.js", // file filter-wildcard
00178                 QStringList() << "application/javascript" // mimetypes
00179             )
00180         );
00181     }
00182 #endif
00183 
00184 #ifdef KROSS_FALCON_LIBRARY
00185     if( void* funcPtr = loadLibrary(KROSS_FALCON_LIBRARY, "krossinterpreter") ) {
00186         d->interpreterinfos.insert("falcon",
00187             new InterpreterInfo("falcon",
00188                 funcPtr, // library
00189                 "*.fal", // file filter-wildcard
00190                 QStringList() << "application/x-falcon" // mimetypes
00191             )
00192         );
00193     }
00194 #endif
00195 
00196 #ifdef KROSS_QTSCRIPT_LIBRARY
00197     if( void* funcPtr = loadLibrary(KROSS_QTSCRIPT_LIBRARY, "krossinterpreter") ) {
00198         d->interpreterinfos.insert("qtscript",
00199             new InterpreterInfo("qtscript",
00200                 funcPtr, // library
00201                 "*.es", // file filter-wildcard
00202                 QStringList() << "application/ecmascript" // mimetypes
00203             )
00204         );
00205     }
00206 #endif
00207 
00208 #ifdef KROSS_LUA_LIBRARY
00209     if( void* funcPtr = loadLibrary(KROSS_LUA_LIBRARY, "krossinterpreter") ) {
00210         d->interpreterinfos.insert("lua",
00211             new InterpreterInfo("lua",
00212                 funcPtr, // library
00213                 "*.lua *.luac", // file filter-wildcard
00214                 QStringList() << "application/x-lua" // mimetypes
00215             )
00216         );
00217     }
00218 #endif
00219 
00220     // fill the list of supported interpreternames.
00221     QHash<QString, InterpreterInfo*>::Iterator it( d->interpreterinfos.begin() );
00222     for(; it != d->interpreterinfos.end(); ++it)
00223         if( it.value() )
00224             d->interpreters << it.key();
00225     d->interpreters.sort();
00226 
00227     // publish ourself.
00228     ChildrenInterface::addObject(this, "Kross");
00229 }
00230 
00231 Manager::~Manager()
00232 {
00233     qDeleteAll(d->wrappers);
00234     qDeleteAll(d->interpreterinfos);
00235     qDeleteAll(d->modules);
00236     delete d->collection;
00237     delete d;
00238 }
00239 
00240 QHash< QString, InterpreterInfo* > Manager::interpreterInfos() const
00241 {
00242     return d->interpreterinfos;
00243 }
00244 
00245 bool Manager::hasInterpreterInfo(const QString& interpretername) const
00246 {
00247     return d->interpreterinfos.contains(interpretername) && d->interpreterinfos[interpretername];
00248 }
00249 
00250 InterpreterInfo* Manager::interpreterInfo(const QString& interpretername) const
00251 {
00252     return hasInterpreterInfo(interpretername) ? d->interpreterinfos[interpretername] : 0;
00253 }
00254 
00255 const QString Manager::interpreternameForFile(const QString& file)
00256 {
00257     QRegExp rx;
00258     rx.setPatternSyntax(QRegExp::Wildcard);
00259     for(QHash<QString, InterpreterInfo*>::Iterator it = d->interpreterinfos.begin(); it != d->interpreterinfos.end(); ++it) {
00260         if( ! it.value() )
00261             continue;
00262         foreach(const QString &wildcard, it.value()->wildcard().split(' ', QString::SkipEmptyParts)) {
00263             rx.setPattern( wildcard );
00264             if( rx.exactMatch(file) )
00265                 return it.value()->interpreterName();
00266         }
00267     }
00268     return QString();
00269 }
00270 
00271 Interpreter* Manager::interpreter(const QString& interpretername) const
00272 {
00273     if( ! hasInterpreterInfo(interpretername) ) {
00274         krosswarning( QString("No such interpreter '%1'").arg(interpretername) );
00275         return 0;
00276     }
00277     return d->interpreterinfos[interpretername]->interpreter();
00278 }
00279 
00280 QStringList Manager::interpreters() const
00281 {
00282     return d->interpreters;
00283 }
00284 
00285 ActionCollection* Manager::actionCollection() const
00286 {
00287     return d->collection;
00288 }
00289 
00290 bool Manager::hasAction(const QString& name)
00291 {
00292     return findChild< Action* >(name) != 0L;
00293 }
00294 
00295 QObject* Manager::action(const QString& name)
00296 {
00297     Action* action = findChild< Action* >(name);
00298     if(! action) {
00299         action = new Action(this, name);
00300 #if 0
00301         d->actioncollection->insert(action); //FIXME should we really remember the action?
00302 #endif
00303     }
00304     return action;
00305 }
00306 
00307 QObject* Manager::module(const QString& modulename)
00308 {
00309     if( d->modules.contains(modulename) ) {
00310         QObject* obj = d->modules[modulename];
00311         if( obj )
00312             return obj;
00313     }
00314 
00315     if( modulename.isEmpty() || modulename.contains( QRegExp("[^a-zA-Z0-9]") ) ) {
00316         krosswarning( QString("Invalid module name '%1'").arg(modulename) );
00317         return 0;
00318     }
00319 
00320     QByteArray libraryname = QString("krossmodule%1").arg(modulename).toLower().toLatin1();
00321 
00322 #if 0
00323     KLibLoader* loader = KLibLoader::self();
00324     KLibrary* lib = loader->library( libraryname, QLibrary::ExportExternalSymbolsHint );
00325     if( ! lib ) { //FIXME this fallback-code should be in KLibLoader imho.
00326         lib = loader->library( QString("lib%1").arg(libraryname), QLibrary::ExportExternalSymbolsHint );
00327         if( ! lib ) {
00328             krosswarning( QString("Failed to load module '%1': %2").arg(modulename).arg(loader->lastErrorMessage()) );
00329             return 0;
00330         }
00331     }
00332 
00333     def_module_func func;
00334     func = (def_module_func) lib->resolveFunction("krossmodule");
00335     if( ! func ) {
00336         krosswarning( QString("Failed to determinate init function in module '%1'").arg(modulename) );
00337         return 0;
00338     }
00339 
00340     QObject* module = (QObject*) (func)(); // call the function
00341     lib->unload(); // unload the library
00342 
00343     if( ! module ) {
00344         krosswarning( QString("Failed to load module object '%1'").arg(modulename) );
00345         return 0;
00346     }
00347 #else
00348     if( void* funcPtr = loadLibrary(libraryname, "krossmodule") ) {
00349         def_module_func func = (def_module_func) funcPtr;
00350         Q_ASSERT( func );
00351         QObject* module = (QObject*) (func)(); // call the function
00352         Q_ASSERT( module );
00353         //krossdebug( QString("Manager::module Module successfully loaded: modulename=%1 module.objectName=%2 module.className=%3").arg(modulename).arg(module->objectName()).arg(module->metaObject()->className()) );
00354         d->modules.insert(modulename, module);
00355         return module;
00356     }
00357     else {
00358         krosswarning( QString("Failed to load module '%1'").arg(modulename) );
00359     }
00360 #endif
00361     return 0;
00362 }
00363 
00364 bool Manager::executeScriptFile(const QUrl& file)
00365 {
00366     krossdebug( QString("Manager::executeScriptFile() file='%1'").arg(file.toString()) );
00367     Action* action = new Action(0 /*no parent*/, file);
00368     action->trigger();
00369     bool ok = ! action->hadError();
00370     delete action; //action->delayedDestruct();
00371     return ok;
00372 }
00373 
00374 void Manager::addQObject(QObject* obj, const QString &name)
00375 {
00376     this->addObject(obj, name);
00377 }
00378 
00379 QObject* Manager::qobject(const QString &name) const
00380 {
00381     return this->object(name);
00382 }
00383 
00384 QStringList Manager::qobjectNames() const
00385 {
00386     return this->objects().keys();
00387 }
00388 
00389 MetaTypeHandler* Manager::metaTypeHandler(const QByteArray& typeName) const
00390 {
00391     return d->wrappers.contains(typeName) ? d->wrappers[typeName] : 0;
00392 }
00393 
00394 void Manager::registerMetaTypeHandler(const QByteArray& typeName, MetaTypeHandler::FunctionPtr* handler)
00395 {
00396     d->wrappers.insert(typeName, new MetaTypeHandler(handler));
00397 }
00398 
00399 void Manager::registerMetaTypeHandler(const QByteArray& typeName, MetaTypeHandler::FunctionPtr2* handler)
00400 {
00401     d->wrappers.insert(typeName, new MetaTypeHandler(handler));
00402 }
00403 
00404 void Manager::registerMetaTypeHandler(const QByteArray& typeName, MetaTypeHandler* handler)
00405 {
00406     d->wrappers.insert(typeName, handler);
00407 }
00408 
00409 bool Manager::strictTypesEnabled() const
00410 {
00411     return d->strictTypesEnabled;
00412 }
00413 
00414 void Manager::setStrictTypesEnabled(bool enabled)
00415 {
00416     d->strictTypesEnabled = enabled;
00417 }
00418 
00419 bool Manager::hasHandlerAssigned(const QByteArray& typeName) const
00420 {
00421     return d->wrappers.contains(typeName);
00422 }
00423 
00424 #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
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
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