00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "manager.h"
00021
00022 #include "../api/interpreter.h"
00023
00024 #include "../api/eventslot.h"
00025 #include "../api/eventsignal.h"
00026
00027
00028 #include "krossconfig.h"
00029 #include "scriptcontainer.h"
00030
00031 #include <qobject.h>
00032 #include <qfile.h>
00033 #include <qregexp.h>
00034 #include <kdebug.h>
00035 #include <kstaticdeleter.h>
00036 #include <klibloader.h>
00037
00038 extern "C"
00039 {
00040 typedef Kross::Api::Object* (*def_module_func)(Kross::Api::Manager*);
00041 }
00042
00043 using namespace Kross::Api;
00044
00045 namespace Kross { namespace Api {
00046
00047
00048 class ManagerPrivate
00049 {
00050 public:
00051
00052 QMap<QString, InterpreterInfo*> interpreterinfos;
00053
00054
00055 QMap<QString, Module::Ptr> modules;
00056 };
00057
00058
00059
00060
00061
00062 static KStaticDeleter<Manager> m_managerdeleter;
00063
00064
00065
00066
00067
00068 static Manager* m_manager = 0;
00069
00070 }}
00071
00072 Manager* Manager::scriptManager()
00073 {
00074 if(! m_manager) {
00075
00076
00077
00078 m_managerdeleter.setObject(m_manager, new Manager());
00079 }
00080
00081
00082 return m_manager;
00083 }
00084
00085 Manager::Manager()
00086 : MainModule("Kross")
00087 , d( new ManagerPrivate() )
00088 {
00089 #ifdef KROSS_PYTHON_LIBRARY
00090 QString pythonlib = QFile::encodeName( KLibLoader::self()->findLibrary(KROSS_PYTHON_LIBRARY) );
00091 if(! pythonlib.isEmpty()) {
00092 InterpreterInfo::Option::Map pythonoptions;
00093 pythonoptions.replace("restricted",
00094 new InterpreterInfo::Option("Restricted", "Restricted Python interpreter", QVariant(false,0))
00095 );
00096 d->interpreterinfos.replace("python",
00097 new InterpreterInfo("python",
00098 pythonlib,
00099 "*.py",
00100 QStringList() << "application/x-python",
00101 pythonoptions
00102 )
00103 );
00104 }
00105 #endif
00106 #ifdef KROSS_RUBY_LIBRARY
00107 QString rubylib = QFile::encodeName( KLibLoader::self()->findLibrary(KROSS_RUBY_LIBRARY) );
00108 if(! rubylib.isEmpty()) {
00109 InterpreterInfo::Option::Map rubyoptions;
00110 rubyoptions.replace("safelevel",
00111 new InterpreterInfo::Option("safelevel", "Level of safety of the Ruby interpreter", QVariant(0))
00112 );
00113 d->interpreterinfos.replace("ruby",
00114 new InterpreterInfo("ruby",
00115 rubylib,
00116 "*.rb",
00117 QStringList() << "application/x-ruby",
00118 rubyoptions
00119 )
00120 );
00121 } else {
00122 kdDebug() << "Ruby interpreter for kross in unavailable" << endl;
00123 }
00124 #endif
00125 }
00126
00127 Manager::~Manager()
00128 {
00129 for(QMap<QString, InterpreterInfo*>::Iterator it = d->interpreterinfos.begin(); it != d->interpreterinfos.end(); ++it)
00130 delete it.data();
00131 delete d;
00132 }
00133
00134 QMap<QString, InterpreterInfo*> Manager::getInterpreterInfos()
00135 {
00136 return d->interpreterinfos;
00137 }
00138
00139 bool Manager::hasInterpreterInfo(const QString& interpretername) const
00140 {
00141 return d->interpreterinfos.contains(interpretername);
00142 }
00143
00144 InterpreterInfo* Manager::getInterpreterInfo(const QString& interpretername)
00145 {
00146 return d->interpreterinfos[interpretername];
00147 }
00148
00149 const QString& Manager::getInterpreternameForFile(const QString& file)
00150 {
00151 QRegExp rx;
00152 rx.setWildcard(true);
00153 for(QMap<QString, InterpreterInfo*>::Iterator it = d->interpreterinfos.begin(); it != d->interpreterinfos.end(); ++it) {
00154 rx.setPattern((*it)->getWildcard());
00155 if( file.find(rx) >= 0 )
00156 return (*it)->getInterpretername();
00157 }
00158 return QString::null;
00159 }
00160
00161 ScriptContainer::Ptr Manager::getScriptContainer(const QString& scriptname)
00162 {
00163
00164
00165
00166
00167 ScriptContainer* scriptcontainer = new ScriptContainer(scriptname);
00168
00169
00170
00171 return scriptcontainer;
00172 }
00173
00174 Interpreter* Manager::getInterpreter(const QString& interpretername)
00175 {
00176 setException(0);
00177
00178 if(! d->interpreterinfos.contains(interpretername)) {
00179 setException( new Exception(QString("No such interpreter '%1'").arg(interpretername)) );
00180 return 0;
00181 }
00182
00183 return d->interpreterinfos[interpretername]->getInterpreter();
00184 }
00185
00186 const QStringList Manager::getInterpreters()
00187 {
00188 QStringList list;
00189
00190 QMap<QString, InterpreterInfo*>::Iterator it( d->interpreterinfos.begin() );
00191 for(; it != d->interpreterinfos.end(); ++it)
00192 list << it.key();
00193
00194
00195
00196 return list;
00197 }
00198
00199 bool Manager::addModule(Module::Ptr module)
00200 {
00201 QString name = module->getName();
00202
00203 d->modules.replace(name, module);
00204 return true;
00205 }
00206
00207 Module::Ptr Manager::loadModule(const QString& modulename)
00208 {
00209 Module::Ptr module = 0;
00210
00211 if(d->modules.contains(modulename)) {
00212 module = d->modules[modulename];
00213 if(module)
00214 return module;
00215 else
00216 kdDebug() << QString("Manager::loadModule(%1) =======> Modulename registered, but module is invalid!").arg(modulename) << endl;
00217 }
00218
00219 KLibLoader* loader = KLibLoader::self();
00220 KLibrary* lib = loader->globalLibrary( modulename.latin1() );
00221 if(! lib) {
00222 kdWarning() << QString("Failed to load module '%1': %2").arg(modulename).arg(loader->lastErrorMessage()) << endl;
00223 return 0;
00224 }
00225 kdDebug() << QString("Successfully loaded module '%1'").arg(modulename) << endl;
00226
00227 def_module_func func;
00228 func = (def_module_func) lib->symbol("init_module");
00229
00230 if(! func) {
00231 kdWarning() << QString("Failed to determinate init function in module '%1'").arg(modulename) << endl;
00232 return 0;
00233 }
00234
00235 module = (Kross::Api::Module*) (func)(this);
00236 lib->unload();
00237
00238 if(! module) {
00239 kdWarning() << QString("Failed to load module '%1'").arg(modulename) << endl;
00240 return 0;
00241 }
00242
00243
00244
00245
00246
00247 return module;
00248 }
00249