Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

omgalgorithmset.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002   omgalgorithmset.cpp  -  description
00003   -------------------
00004 begin                : March 2006
00005 copyright            : (C) 2003 by Tim Sutton
00006 email                : tim@linfiniti.com
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include "omgalgorithmset.h"
00019 #include "omgmodellerplugininterface.h"
00020 #include "omgui.h" //provides anciliary helper functions like getting app paths
00021 #include "omgmodellerpluginregistry.h"
00022 #include <QApplication>
00023 #include <QDebug>
00024 #include <QMapIterator> 
00025 #include <QStringList>
00026 #include <QDomDocument>
00027 #include <QDomElement>
00028 #include <QDir>
00029 #include <cassert>
00030 OmgAlgorithmSet::OmgAlgorithmSet() : OmgSerialisable() 
00031 {
00032 
00033 }
00034 OmgAlgorithmSet::~OmgAlgorithmSet()
00035 {
00036 
00037 }
00038 bool OmgAlgorithmSet::addAlgorithm(OmgAlgorithm theAlgorithm,bool theOverwriteFlag)
00039 {
00040   //check if algorithm is already in the hash and if it is dont add it
00041   if (mAlgorithmsMap.contains(theAlgorithm.name()) && theOverwriteFlag==false)
00042   {
00043     //qDebug("Algorithm not added as overwrite mode is false");
00044     return false;
00045   }
00046   //first remove the old one if applicable
00047   if (mAlgorithmsMap.contains(theAlgorithm.name()))
00048   {
00049     mAlgorithmsMap.remove(theAlgorithm.name());
00050   }
00051   //now we have ensured the alg name is unique or overwriteable, we can add it
00052   mAlgorithmsMap[theAlgorithm.name()]=theAlgorithm;
00053   return true;
00054 }
00055 bool OmgAlgorithmSet::removeAlgorithm(OmgAlgorithm theAlgorithm)
00056 {
00057   mAlgorithmsMap.remove(theAlgorithm.name());
00058   return true;
00059 }
00060 bool OmgAlgorithmSet::removeAlgorithm(QString theAlgorithm)
00061 {
00062   mAlgorithmsMap.remove(theAlgorithm);
00063   return true;
00064 }
00065 
00066 //
00067 // Accessors
00068 //
00069 
00070 QString OmgAlgorithmSet::name() const
00071 {
00072   return mName;
00073 }
00074 QString OmgAlgorithmSet::description() const
00075 {
00076   return mDescription;
00077 }
00078 
00079 //
00080 // Mutators
00081 //
00082 
00083 void OmgAlgorithmSet::setName(QString theName)
00084 {
00085   mName=theName;
00086 }
00087 void OmgAlgorithmSet::setDescription(QString theDescription)
00088 {
00089   mDescription = theDescription;
00090 }
00091 
00092 
00093 
00094 //
00095 // Ancilliary methods
00096 //
00097 
00098 void OmgAlgorithmSet::clear()
00099 {
00100   mAlgorithmsMap.clear();
00101 }
00102 int OmgAlgorithmSet::count() const
00103 {
00104   return mAlgorithmsMap.count();
00105 }
00106 
00107 QString OmgAlgorithmSet::toString()
00108 {
00110   return QString("");
00111 }
00112 QStringList OmgAlgorithmSet::nameList()
00113 {
00114   QStringList myList;
00115   AlgorithmsMap::iterator myIterator;
00116   for (myIterator = mAlgorithmsMap.begin(); myIterator != mAlgorithmsMap.end(); ++myIterator)
00117   {
00118     OmgAlgorithm myAlgorithm = myIterator.value();
00119     myList.append(myAlgorithm.name());
00120   }
00121   return myList;
00122 }
00123 
00124 OmgAlgorithm OmgAlgorithmSet::getAlgorithm (QString theGuid)
00125 {
00126   AlgorithmsMap::iterator myIterator;
00127   for (myIterator = mAlgorithmsMap.begin(); myIterator != mAlgorithmsMap.end(); ++myIterator)
00128   {
00129     OmgAlgorithm myAlgorithm = myIterator.value();
00130     if (myAlgorithm.guid() == theGuid)
00131     {
00132       return myAlgorithm;
00133     }
00134   }
00135   //this is bad!
00136   return OmgAlgorithm();
00137 }
00138 
00139 bool OmgAlgorithmSet::contains(QString theName)
00140 {
00141   return mAlgorithmsMap.contains(theName);
00142 }
00143 //
00144 // Overloaded operators
00145 //
00146 
00147 OmgAlgorithm OmgAlgorithmSet::operator [] (int thePosition)
00148 {
00149 
00150  QString myKey = mAlgorithmsMap.keys().at(thePosition);
00151  if (!myKey.isEmpty())
00152  {
00153    return mAlgorithmsMap.value(myKey);
00154  }
00156  OmgAlgorithm myAlgorithm;
00157  return myAlgorithm;
00158 }
00159 
00160 //
00161 // Serialisation stuff
00162 //
00163 QString OmgAlgorithmSet::toXml() const
00164 {
00165   QString myString = QString("    <Algorithms count=\"" 
00166       + QString::number(count())+"\" Name=\"" + mName + "\" Description=\"" + mDescription + "\">\n");
00167   
00168   AlgorithmsMap::const_iterator myIterator;
00169   for (myIterator = mAlgorithmsMap.begin(); myIterator != mAlgorithmsMap.end(); ++myIterator)
00170   {
00171     OmgAlgorithm myAlgorithm = myIterator.value();
00172     myString += myAlgorithm.toXml() + "\n";
00173   }
00174   myString+=QString("    </Algorithms>\n");
00175 
00176   return myString;
00177 }
00178 
00179 
00180 
00181 QString OmgAlgorithmSet::toHtml()
00182 {
00183   //Iterate through creation algorithms
00184   QString myString;
00185   AlgorithmsMap::iterator myIterator;
00186   for (myIterator = mAlgorithmsMap.begin(); myIterator != mAlgorithmsMap.end(); ++myIterator)
00187   {
00188     OmgAlgorithm myAlgorithm = myIterator.value();
00189     myString+=myAlgorithm.toHtml();
00190     myString += "<hr/>\n";
00191   }
00192   return myString;
00193 }
00194 
00195 bool OmgAlgorithmSet::fromXml(const QString theXml)
00196 {
00197   QDomDocument myDocument("mydocument");
00198   QString myError;
00199   int myErrorLine;
00200   int myErrorColumn;
00201   if (!myDocument.setContent(theXml, true, &myError, &myErrorLine, &myErrorColumn)) 
00202   {
00203     qDebug(QString("Parse error at line %1, column %2:\n%3")
00204     .arg(myErrorLine)
00205     .arg(myErrorColumn)
00206     .arg(myError)
00207     .toLocal8Bit());
00208     return false;
00209   }
00210   QDomElement myTopElement = myDocument.firstChildElement("Algorithms");
00211   //QDomElement myTopElement = myDocument.firstChild().toElement();
00212   //qDebug("Top Element" + myTopElement.tagName().toLocal8Bit());
00213   //get the name and descriptionattributes from the top level tag
00214   mName=myTopElement.attribute("Name");
00215   mDescription=myTopElement.attribute("Description");
00216   //now get the algorithm names from the nested tags
00217   QDomElement myElement = myTopElement.firstChildElement("Algorithm");
00218   while(!myElement.isNull()) 
00219   {
00220     if (myElement.tagName()!="Algorithm")
00221     {
00222       myElement = myElement.nextSiblingElement();
00223       continue;
00224     }
00225     //get a textual xml representation of the param tag
00226     QDomDocument myAlgorithmDoc("Algorithm");
00227     //note we need to do a deep copy here because the
00228     //element is shared otherwise and when we
00229     //reparent it the loop stops after the first node
00230     //as no more siblings are found!
00231     QDomElement myCopy = myElement.cloneNode().toElement();
00232     myAlgorithmDoc.appendChild(myCopy);
00233     QString myXml = myAlgorithmDoc.toString();
00234     //qDebug("------- Adding alg to algset -----------");
00235     //now hand over the xml snippet to the alg parameter class to be deserialised
00236     OmgAlgorithm myAlgorithm;
00237     myAlgorithm.fromXml(myXml);
00238     addAlgorithm(myAlgorithm);
00239     myElement = myElement.nextSiblingElement();
00240   }
00241   return true;
00242 }
00243     
00244 OmgAlgorithmSet OmgAlgorithmSet::getFromActivePlugin()
00245 {
00246   /* This is the Abstract plugin type. Depending on the users
00247    * options, it will be initialised to either the OmgModellerLocalPlugin
00248    * or OmgModellerWebServices plugin (or possibly other plugin types in 
00249    * the future) 
00250    */
00251   //qDebug("AlgorithmSet calling OmGui to get the modeller plugin");
00252   //note this pointer should *not* be deleted afterwards because its managed by the registry!!
00253   OmgModellerPluginInterface * mypModellerPlugin = OmgModellerPluginRegistry::instance()->getPlugin();
00254   //qDebug("AlgorithmSet designer testing if returned modeller plugin is ok");
00255   if(!mypModellerPlugin)
00256   {
00257     //this is bad! TODO notify user he has no useable adapters
00258     //TODO handle this more gracefully than asserting!
00259     //qDebug("AlgorithmSet Error no valid modelling adapters could be loaded");
00260     //qDebug("No modelling plugins could be found.\nPlease report this problem to you system administrator or the openModeller developers.");
00261     //assert ("Undefined adapter type in __FILE__  , line  __LINE__");
00262     OmgAlgorithmSet myAlgorithmSet;
00263     return myAlgorithmSet;
00264   }
00265   else
00266   {
00267     //qDebug("Plugin is good to go....");
00268   }
00269   //now we can go on to use our plugin...
00270   OmgAlgorithmSet myAlgorithmSet = mypModellerPlugin->getAlgorithmSet();
00271   return myAlgorithmSet;
00272 }
00273 
00274 void OmgAlgorithmSet::loadAlgorithms(QString theSearchDir)
00275 {
00276   QDir myDirectory(theSearchDir);
00277   myDirectory.setFilter(QDir::Dirs | QDir::Files | QDir::NoSymLinks );
00278   QFileInfoList myList = myDirectory.entryInfoList();
00279   for (unsigned int i = 0; i < static_cast<unsigned int>(myList.size()); ++i)
00280   {
00281     QFileInfo myFileInfo = myList.at(i);
00282     //Ignore directories
00283     if(myFileInfo.fileName() == "." ||myFileInfo.fileName() == ".." )
00284     {
00285       continue;
00286     }
00287     //if the filename ends in .xml try to load it into our layerSets listing
00288     if(myFileInfo.completeSuffix()=="xml")
00289     {
00290       OmgAlgorithm myAlgorithm;
00291       myAlgorithm.fromXmlFile(myFileInfo.filePath() );
00292       if (myAlgorithm.name().isEmpty())
00293       {
00294         continue;
00295       }
00296       //define the origin of the algorithm - this is used by e.g. the algmanager
00297       //in the gui to differentiate between user profiles and profiles 
00298       //obtained from the plugin
00299       //I have created some default alg proiles which should be 
00300       //treated as system algs. These are for algs like svm that
00301       //have several 'sub algorithms'.
00302       if (myFileInfo.fileName().startsWith("algorithm"))
00303       {
00304         myAlgorithm.setOrigin(OmgAlgorithm::ADAPTERPROFILE);
00305       }
00306       else
00307       {
00308         myAlgorithm.setOrigin(OmgAlgorithm::USERPROFILE);
00309       }
00310       addAlgorithm(myAlgorithm);
00311     }
00312   }
00313 }
00314 
00315 void OmgAlgorithmSet::saveAlgorithms(QString theSaveDir, bool theUserProfilesFlag)
00316 {
00317   AlgorithmsMap::iterator myIterator;
00318   for (myIterator = mAlgorithmsMap.begin(); myIterator != mAlgorithmsMap.end(); ++myIterator)
00319   {
00320     OmgAlgorithm myAlgorithm = myIterator.value();
00321     if ((myAlgorithm.origin()!=OmgAlgorithm::USERPROFILE) && theUserProfilesFlag)
00322     {
00323       //flag says only write alg profiles to disk that are tagged as origin user profile
00324       //so skipe this one...
00325       continue;
00326     }
00327     QString myString = myAlgorithm.toXml();
00328     QFile myFile(theSaveDir + myAlgorithm.guid() + ".xml");
00329     if (!myFile.open(QIODevice::WriteOnly | QIODevice::Text))
00330     {
00331       continue;
00332     }
00333     QTextStream myStream(&myFile);
00334     myStream << myString;
00335     myFile.close();
00336   }
00337 }
00338 

Generated on Mon Apr 28 15:08:03 2008 for openModellerDesktop by  doxygen 1.4.1-20050210