00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "manager.h"
00021 #include "interpreter.h"
00022 #include "action.h"
00023 #include "actioncollection.h"
00024
00025
00026 #include <QtCore/QObject>
00027 #include <QtCore/QArgument>
00028 #include <QtCore/QFile>
00029 #include <QtCore/QRegExp>
00030 #include <QtCore/QFileInfo>
00031
00032 #include <klibloader.h>
00033
00034 extern "C"
00035 {
00036 typedef QObject* (*def_module_func)();
00037 }
00038
00039 using namespace Kross;
00040
00041 namespace Kross {
00042
00044 class Manager::Private
00045 {
00046 public:
00048 QHash< QString, InterpreterInfo* > interpreterinfos;
00049
00051 QStringList interpreters;
00052
00054 QHash< QString, QPointer<QObject> > modules;
00055
00057 ActionCollection* collection;
00058 };
00059
00060 }
00061
00062
00063 Manager& Manager::self()
00064 {
00065 K_GLOBAL_STATIC(Manager, _self)
00066 return *_self;
00067 }
00068
00069 Manager::Manager()
00070 : QObject()
00071 , ChildrenInterface()
00072 , d( new Private() )
00073 {
00074 setObjectName("Kross");
00075 d->collection = new ActionCollection("main");
00076
00077 #ifdef KROSS_PYTHON_LIBRARY
00078 QString pythonlib = QFile::encodeName( KLibLoader::self()->findLibrary(QLatin1String(KROSS_PYTHON_LIBRARY)) );
00079 if(! pythonlib.isEmpty()) {
00080 InterpreterInfo::Option::Map pythonoptions;
00081 d->interpreterinfos.insert("python",
00082 new InterpreterInfo("python",
00083 pythonlib,
00084 "*.py",
00085 QStringList() << "text/x-python",
00086 pythonoptions
00087 )
00088 );
00089 } else {
00090 #ifdef KROSS_INTERPRETER_DEBUG
00091 krossdebug("Python interpreter for kross is unavailable");
00092 #endif
00093 }
00094 #endif
00095
00096 #ifdef KROSS_RUBY_LIBRARY
00097 QString rubylib = QFile::encodeName( KLibLoader::self()->findLibrary(QLatin1String(KROSS_RUBY_LIBRARY)) );
00098 if(! rubylib.isEmpty()) {
00099 InterpreterInfo::Option::Map rubyoptions;
00100 rubyoptions.insert("safelevel",
00101 new InterpreterInfo::Option(
00102 i18n("Level of safety of the Ruby interpreter"),
00103 QVariant(0)
00104 )
00105 );
00106 d->interpreterinfos.insert("ruby",
00107 new InterpreterInfo("ruby",
00108 rubylib,
00109 "*.rb",
00110 QStringList() << "application/x-ruby",
00111 rubyoptions
00112 )
00113 );
00114 } else {
00115 #ifdef KROSS_INTERPRETER_DEBUG
00116 krossdebug("Ruby interpreter for kross is unavailable");
00117 #endif
00118 }
00119 #endif
00120
00121 #ifdef KROSS_JAVA_LIBRARY
00122 QString javalib = QFile::encodeName( KLibLoader::self()->findLibrary(QLatin1String(KROSS_JAVA_LIBRARY)) );
00123 if(! javalib.isEmpty()) {
00124 InterpreterInfo::Option::Map javaoptions;
00125 d->interpreterinfos.insert("java",
00126 new InterpreterInfo("java",
00127 javalib,
00128 "*.java *.class *.jar",
00129 QStringList() << "application/java",
00130 javaoptions
00131 )
00132 );
00133 } else {
00134 #ifdef KROSS_INTERPRETER_DEBUG
00135 krossdebug("KDE Java interpreter for kross is unavailable");
00136 #endif
00137 }
00138 #endif
00139
00140 #ifdef KROSS_KJS_LIBRARY
00141 QString kjslib = QFile::encodeName( KLibLoader::self()->findLibrary(QLatin1String(KROSS_KJS_LIBRARY)) );
00142 if(! kjslib.isEmpty()) {
00143 InterpreterInfo::Option::Map kjsoptions;
00144 kjsoptions.insert("restricted",
00145 new InterpreterInfo::Option(
00146 i18n("Restricted mode for untrusted scripts"),
00147 QVariant(true)
00148 )
00149 );
00150 d->interpreterinfos.insert("javascript",
00151 new InterpreterInfo("javascript",
00152 kjslib,
00153 "*.js",
00154 QStringList() << "application/javascript",
00155 kjsoptions
00156 )
00157 );
00158 } else {
00159 #ifdef KROSS_INTERPRETER_DEBUG
00160 krossdebug("KDE JavaScript interpreter for kross is unavailable");
00161 #endif
00162 }
00163 #endif
00164
00165 #ifdef KROSS_FALCON_LIBRARY
00166 QString falconlib = QFile::encodeName( KLibLoader::self()->findLibrary(QLatin1String(KROSS_FALCON_LIBRARY)) );
00167 if(! falconlib.isEmpty()) {
00168 InterpreterInfo::Option::Map falconptions;
00169 d->interpreterinfos.insert("falcon",
00170 new InterpreterInfo("falcon",
00171 falconlib,
00172 "*.fal",
00173 QStringList() << "application/x-falcon",
00174 falconptions
00175 )
00176 );
00177 } else {
00178 #ifdef KROSS_INTERPRETER_DEBUG
00179 krossdebug("Falcon interpreter for kross is unavailable");
00180 #endif
00181 }
00182 #endif
00183
00184
00185 QHash<QString, InterpreterInfo*>::Iterator it( d->interpreterinfos.begin() );
00186 for(; it != d->interpreterinfos.end(); ++it)
00187 if( it.value() )
00188 d->interpreters << it.key();
00189
00190
00191
00192 ChildrenInterface::addObject(this, "Kross");
00193 }
00194
00195 Manager::~Manager()
00196 {
00197 qDeleteAll(d->interpreterinfos.values());
00198 qDeleteAll(d->modules.values());
00199 delete d->collection;
00200 delete d;
00201 }
00202
00203 QHash< QString, InterpreterInfo* > Manager::interpreterInfos() const
00204 {
00205 return d->interpreterinfos;
00206 }
00207
00208 bool Manager::hasInterpreterInfo(const QString& interpretername) const
00209 {
00210 return d->interpreterinfos.contains(interpretername) && d->interpreterinfos[interpretername];
00211 }
00212
00213 InterpreterInfo* Manager::interpreterInfo(const QString& interpretername) const
00214 {
00215 return hasInterpreterInfo(interpretername) ? d->interpreterinfos[interpretername] : 0;
00216 }
00217
00218 const QString Manager::interpreternameForFile(const QString& file)
00219 {
00220 QRegExp rx;
00221 rx.setPatternSyntax(QRegExp::Wildcard);
00222 for(QHash<QString, InterpreterInfo*>::Iterator it = d->interpreterinfos.begin(); it != d->interpreterinfos.end(); ++it) {
00223 if( ! it.value() )
00224 continue;
00225 foreach(QString wildcard, it.value()->wildcard().split(" ", QString::SkipEmptyParts)) {
00226 rx.setPattern( wildcard );
00227 if( rx.exactMatch(file) )
00228 return it.value()->interpreterName();
00229 }
00230 }
00231 return QString();
00232 }
00233
00234 Interpreter* Manager::interpreter(const QString& interpretername) const
00235 {
00236 if( ! hasInterpreterInfo(interpretername) ) {
00237 krosswarning( QString("No such interpreter '%1'").arg(interpretername) );
00238 return 0;
00239 }
00240 return d->interpreterinfos[interpretername]->interpreter();
00241 }
00242
00243 QStringList Manager::interpreters() const
00244 {
00245 return d->interpreters;
00246 }
00247
00248 ActionCollection* Manager::actionCollection() const
00249 {
00250 return d->collection;
00251 }
00252
00253 bool Manager::hasAction(const QString& name)
00254 {
00255 return findChild< Action* >(name) != 0L;
00256 }
00257
00258 QObject* Manager::action(const QString& name)
00259 {
00260 Action* action = findChild< Action* >(name);
00261 if(! action) {
00262 action = new Action(this, name);
00263 #if 0
00264 d->actioncollection->insert(action);
00265 #endif
00266 }
00267 return action;
00268 }
00269
00270 QObject* Manager::module(const QString& modulename)
00271 {
00272 if( d->modules.contains(modulename) ) {
00273 QObject* obj = d->modules[modulename];
00274 if( obj )
00275 return obj;
00276 }
00277
00278 if( modulename.isEmpty() || modulename.contains( QRegExp("[^a-zA-Z0-9]") ) ) {
00279 krosswarning( QString("Invalid module name '%1'").arg(modulename) );
00280 return 0;
00281 }
00282
00283 QString libraryname = QString("krossmodule%1").arg(modulename).toLower();
00284 KLibLoader* loader = KLibLoader::self();
00285 KLibrary* lib = loader->library( libraryname, QLibrary::ExportExternalSymbolsHint );
00286 if( ! lib ) {
00287 lib = loader->library( QString("lib%1").arg(libraryname), QLibrary::ExportExternalSymbolsHint );
00288 if( ! lib ) {
00289 krosswarning( QString("Failed to load module '%1': %2").arg(modulename).arg(loader->lastErrorMessage()) );
00290 return 0;
00291 }
00292 }
00293
00294 def_module_func func;
00295 func = (def_module_func) lib->resolveFunction("krossmodule");
00296 if( ! func ) {
00297 krosswarning( QString("Failed to determinate init function in module '%1'").arg(modulename) );
00298 return 0;
00299 }
00300
00301 QObject* module = (QObject*) (func)();
00302 lib->unload();
00303
00304 if( ! module ) {
00305 krosswarning( QString("Failed to load module object '%1'").arg(modulename) );
00306 return 0;
00307 }
00308
00309
00310 d->modules.insert(modulename, module);
00311 return module;
00312 }
00313
00314 bool Manager::executeScriptFile(const QString& file)
00315 {
00316 krossdebug( QString("Manager::executeScriptFile() file='%1'").arg(file) );
00317 Action* action = new Action(0 , QUrl(file));
00318 action->trigger();
00319 bool ok = ! action->hadError();
00320 delete action;
00321 return ok;
00322 }
00323
00324 #include "manager.moc"