lib

manager.cpp

00001 /***************************************************************************
00002  * manager.cpp
00003  * This file is part of the KDE project
00004  * copyright (C)2004-2005 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 
00022 #include "../api/interpreter.h"
00023 //#include "../api/qtobject.h"
00024 #include "../api/eventslot.h"
00025 #include "../api/eventsignal.h"
00026 //#include "../api/script.h"
00027 
00028 #include "krossconfig.h"
00029 #include "scriptcontainer.h"
00030 
00031 #include <qobject.h>
00032 #include <qfile.h>
00033 #include <qregexp.h>
00034 
00035 #include <klibloader.h>
00036 #include <klocale.h>
00037 #include <kstaticdeleter.h>
00038 
00039 extern "C"
00040 {
00041     typedef Kross::Api::Object* (*def_module_func)(Kross::Api::Manager*);
00042 }
00043 
00044 using namespace Kross::Api;
00045 
00046 namespace Kross { namespace Api {
00047 
00049     class ManagerPrivate
00050     {
00051         public:
00053             QMap<QString, InterpreterInfo*> interpreterinfos;
00054 
00056             QMap<QString, Module::Ptr> modules;
00057     };
00058 
00063     static KSharedPtr<Manager> m_manager = KSharedPtr<Manager>(0);
00064 
00065 }}
00066 
00067 Manager* Manager::scriptManager()
00068 {
00069     if(! m_manager.data()) {
00070         // Create the Manager-singleton on demand.
00071         m_manager = KSharedPtr<Manager>( new Manager() );
00072     }
00073 
00074     // and finally return the singleton.
00075     return m_manager.data();
00076 }
00077 
00078 Manager::Manager()
00079     : MainModule("Kross") // the manager has the name "Kross"
00080     , d( new ManagerPrivate() )
00081 {
00082 #ifdef KROSS_PYTHON_LIBRARY
00083     QString pythonlib = QFile::encodeName( KLibLoader::self()->findLibrary(KROSS_PYTHON_LIBRARY) );
00084     if(! pythonlib.isEmpty()) { // If the Kross Python plugin exists we offer it as supported scripting language.
00085         InterpreterInfo::Option::Map pythonoptions;
00086         pythonoptions.replace("restricted",
00087             new InterpreterInfo::Option("Restricted", "Restricted Python interpreter", QVariant(false,0))
00088         );
00089         d->interpreterinfos.replace("python",
00090             new InterpreterInfo("python",
00091                 pythonlib, // library
00092                 "*.py", // file filter-wildcard
00093                 QStringList() << /* "text/x-python" << */ "application/x-python", // mimetypes
00094                 pythonoptions // options
00095             )
00096         );
00097     }
00098 #endif
00099 #ifdef KROSS_RUBY_LIBRARY
00100     QString rubylib = QFile::encodeName( KLibLoader::self()->findLibrary(KROSS_RUBY_LIBRARY) );
00101     if(! rubylib.isEmpty()) { // If the Kross Ruby plugin exists we offer it as supported scripting language.
00102       InterpreterInfo::Option::Map rubyoptions;
00103       rubyoptions.replace("safelevel",
00104                           new InterpreterInfo::Option("safelevel", "Level of safety of the Ruby interpreter", QVariant(0)) // 0 -> unsafe, 4 -> very safe
00105                            );
00106       d->interpreterinfos.replace("ruby",
00107                                   new InterpreterInfo("ruby",
00108                                       rubylib, // library
00109                                       "*.rb", // file filter-wildcard
00110                                       QStringList() << /* "text/x-ruby" << */ "application/x-ruby", // mimetypes
00111                                       rubyoptions // options
00112                                                      )
00113                                  );
00114     } else {
00115         krossdebug("Ruby interpreter for kross in unavailable");
00116     }
00117 #endif
00118 }
00119 
00120 Manager::~Manager()
00121 {
00122     for(QMap<QString, InterpreterInfo*>::Iterator it = d->interpreterinfos.begin(); it != d->interpreterinfos.end(); ++it)
00123         delete it.data();
00124     delete d;
00125 }
00126 
00127 QMap<QString, InterpreterInfo*> Manager::getInterpreterInfos()
00128 {
00129     return d->interpreterinfos;
00130 }
00131 
00132 bool Manager::hasInterpreterInfo(const QString& interpretername) const
00133 {
00134     return d->interpreterinfos.contains(interpretername);
00135 }
00136 
00137 InterpreterInfo* Manager::getInterpreterInfo(const QString& interpretername)
00138 {
00139     return d->interpreterinfos[interpretername];
00140 }
00141 
00142 const QString Manager::getInterpreternameForFile(const QString& file)
00143 {
00144     QRegExp rx;
00145     rx.setWildcard(true);
00146     for(QMap<QString, InterpreterInfo*>::Iterator it = d->interpreterinfos.begin(); it != d->interpreterinfos.end(); ++it) {
00147         rx.setPattern((*it)->getWildcard());
00148         if( file.find(rx) >= 0 )
00149             return (*it)->getInterpretername();
00150     }
00151     return QString::null;
00152 }
00153 
00154 ScriptContainer::Ptr Manager::getScriptContainer(const QString& scriptname)
00155 {
00156     //TODO at the moment we don't share ScriptContainer instances.
00157 
00158     //if(d->m_scriptcontainers.contains(scriptname))
00159     //    return d->m_scriptcontainers[scriptname];
00160     ScriptContainer* scriptcontainer = new ScriptContainer(scriptname);
00161     //ScriptContainer script(this, scriptname);
00162     //d->m_scriptcontainers.replace(scriptname, scriptcontainer);
00163 
00164     return scriptcontainer;
00165 }
00166 
00167 Interpreter* Manager::getInterpreter(const QString& interpretername)
00168 {
00169     setException(0); // clear previous exceptions
00170 
00171     if(! d->interpreterinfos.contains(interpretername)) {
00172         setException( new Exception(i18n("No such interpreter '%1'").arg(interpretername)) );
00173         return 0;
00174     }
00175 
00176     return d->interpreterinfos[interpretername]->getInterpreter();
00177 }
00178 
00179 const QStringList Manager::getInterpreters()
00180 {
00181     QStringList list;
00182 
00183     QMap<QString, InterpreterInfo*>::Iterator it( d->interpreterinfos.begin() );
00184     for(; it != d->interpreterinfos.end(); ++it)
00185         list << it.key();
00186 
00187 //list << "TestCase";
00188 
00189     return  list;
00190 }
00191 
00192 bool Manager::addModule(Module::Ptr module)
00193 {
00194     QString name = module->getName();
00195     //if( d->modules.contains(name) ) return false;
00196     d->modules.replace(name, module);
00197     return true;
00198 }
00199 
00200 Module::Ptr Manager::loadModule(const QString& modulename)
00201 {
00202     Module::Ptr module = 0;
00203 
00204     if(d->modules.contains(modulename)) {
00205         module = d->modules[modulename];
00206         if(module)
00207             return module;
00208         else
00209             krossdebug( QString("Manager::loadModule(%1) =======> Modulename registered, but module is invalid!").arg(modulename) );
00210     }
00211 
00212     KLibLoader* loader = KLibLoader::self();
00213     KLibrary* lib = loader->globalLibrary( modulename.latin1() );
00214     if(! lib) {
00215         krosswarning( QString("Failed to load module '%1': %2").arg(modulename).arg(loader->lastErrorMessage()) );
00216         return 0;
00217     }
00218     krossdebug( QString("Successfully loaded module '%1'").arg(modulename) );
00219 
00220     def_module_func func;
00221     func = (def_module_func) lib->symbol("init_module");
00222 
00223     if(! func) {
00224         krosswarning( QString("Failed to determinate init function in module '%1'").arg(modulename) );
00225         return 0;
00226     }
00227 
00228     try {
00229         module = (Kross::Api::Module*) (func)(this);
00230     }
00231     catch(Kross::Api::Exception::Ptr e) {
00232         krosswarning( e->toString() );
00233         module = 0;
00234     }
00235     lib->unload();
00236 
00237     if(! module) {
00238         krosswarning( QString("Failed to load module '%1'").arg(modulename) );
00239         return 0;
00240     }
00241 
00242     // Don't remember module cause we like to have freeing it handled by the caller.
00243     //d->modules.replace(modulename, module);
00244 
00245     //krossdebug( QString("Kross::Api::Manager::loadModule modulename='%1' module='%2'").arg(modulename).arg(module->toString()) );
00246     return module;
00247 }
00248 
KDE Home | KDE Accessibility Home | Description of Access Keys