TinkerCell Core 1.0
TinkerCell's Core library providing all basic functionalities
Ontology.cpp
Go to the documentation of this file.
00001 #include "ItemFamily.h"
00002 #include "Ontology.h"
00003 
00004 #ifndef NOT_USING_RAPTOR
00005 extern "C"
00006 {
00007         #include "raptor.h"
00008 }
00009 #endif
00010 
00011 namespace Tinkercell
00012 {
00013                 NodeFamily * Ontology::nodeFamily(const QString& s0)
00014                 {
00015                         QString s = s0.toLower();
00016                         if (nodeFamilies.contains(s))
00017                                 return nodeFamilies.value(s);
00018                         else
00019                                 return 0;
00020                 }
00021                 ConnectionFamily  * Ontology::connectionFamily(const QString& s0)
00022                 {
00023                         QString s = s0.toLower();
00024                         if (connectionFamilies.contains(s))
00025                                 return connectionFamilies.value(s);
00026                         else
00027                                 return 0;
00028                 }
00029                 bool Ontology::insertNodeFamily(const QString & s0, NodeFamily * ptr)
00030                 {
00031                         QString s = s0.toLower();
00032                         if (!ptr || s.isEmpty() || nodeFamilies.contains(s)) return false;
00033                         nodeFamilies.insert(s,ptr);
00034                         return true;
00035                 }
00036                 bool Ontology::insertConnectionFamily(const QString & s0, ConnectionFamily * ptr)
00037                 {
00038                         QString s = s0.toLower();
00039                         if (!ptr || s.isEmpty() || connectionFamilies.contains(s)) return false;
00040                         connectionFamilies.insert(s,ptr);
00041                         return true;
00042                 }
00043                 QList<NodeFamily*> Ontology::allNodeFamilies()
00044                 {
00045                         QList<NodeFamily*> all = nodeFamilies.values(), unique;
00046                         for (int i=0; i < all.size(); ++i)
00047                                 if (all[i] && !unique.contains(all[i]))
00048                                         unique += all[i];
00049                         return unique;
00050                 }
00051                 QList<ConnectionFamily*> Ontology::allConnectionFamilies()
00052                 {
00053                         QList<ConnectionFamily*> all = connectionFamilies.values(), unique;
00054                         for (int i=0; i < all.size(); ++i)
00055                                 if (all[i] && !unique.contains(all[i]))
00056                                         unique += all[i];
00057                         return unique;
00058                 }
00059                 QStringList Ontology::allNodeFamilyNames()
00060                 {
00061                         QStringList keys(nodeFamilies.keys()), names;
00062                         for (int i=0; i < keys.size(); ++i)
00063                                 if (nodeFamilies[ keys[i] ] && nodeFamilies[ keys[i] ]->name() == keys[i])
00064                                         names << keys[i];
00065                         return names;
00066                 }
00067                 QStringList Ontology::allConnectionFamilyNames()
00068                 {
00069                         QStringList keys(connectionFamilies.keys()), names;
00070                         for (int i=0; i < keys.size(); ++i)
00071                                 if (connectionFamilies[ keys[i] ] && connectionFamilies[ keys[i] ]->name() == keys[i])
00072                                         names << keys[i];
00073                         return names;
00074                 }
00075                 
00076 #ifndef NOT_USING_RAPTOR
00077                 static QStringList lastReadFamilyNames;
00078                 static void read_node_triple(void* user_data, raptor_statement* triple) 
00079                 {
00080                         QString s,p,o;
00081                         NodeFamily *family1 = 0, *family2 = 0;
00082 
00083                         if (triple->subject->type == RAPTOR_TERM_TYPE_URI)
00084                                 s = QObject::tr((char*)(raptor_uri_as_string(triple->subject->value.uri)));
00085                         else
00086                         if (triple->subject->type == RAPTOR_TERM_TYPE_LITERAL)
00087                                 s = QObject::tr((char*)(triple->subject->value.literal.string));
00088 
00089                         if (triple->predicate->type == RAPTOR_TERM_TYPE_URI)
00090                                 p = QObject::tr((char*)(raptor_uri_as_string(triple->predicate->value.uri)));
00091                         else
00092                         if (triple->predicate->type == RAPTOR_TERM_TYPE_LITERAL)
00093                                 p = QObject::tr((char*)(triple->predicate->value.literal.string));
00094 
00095                         if (triple->object->type == RAPTOR_TERM_TYPE_URI)
00096                                 o = QObject::tr((char*)(raptor_uri_as_string(triple->object->value.uri)));
00097                         else
00098                         if (triple->object->type == RAPTOR_TERM_TYPE_LITERAL)
00099                                 o = QObject::tr((char*)(triple->object->value.literal.string));
00100 
00101                         if (!s.isEmpty()         && !p.isEmpty() && !o.isEmpty())
00102                         {
00103                                 //insert s as new family
00104                                 s = s.toLower();
00105                                 family1 = Ontology::nodeFamily(s);
00106                                 if (!family1)
00107                                 {
00108                                         family1 = new NodeFamily(s);
00109                                         lastReadFamilyNames << family1->name();
00110                                         Ontology::insertNodeFamily(family1->name(),family1);
00111                                         if (s != family1->name())
00112                                                 Ontology::insertNodeFamily(s,family1);
00113                                 }
00114                                 if (!lastReadFamilyNames.contains(family1->name()))
00115                                         lastReadFamilyNames << family1->name();
00116                                 if (p == QObject::tr("a") || p == QObject::tr("isa") || p == QObject::tr("is a"))  //if isa relationship
00117                                 {
00118                                         o = o.toLower(); 
00119                                         family2 = Ontology::nodeFamily(o);
00120                                         if (!family2)  //insert o as new family
00121                                         {
00122                                                 family2 = new NodeFamily(o);
00123                                                 Ontology::insertNodeFamily(o,family2);
00124                                                 Ontology::insertNodeFamily(family2->name(),family2);
00125                                                 if (o != family2->name())
00126                                                         Ontology::insertNodeFamily(o,family2);
00127                                         }
00128                                         family1->setParent(family2);
00129                                         if (!lastReadFamilyNames.contains(family2->name()))
00130                                                 lastReadFamilyNames << family2->name();
00131                                 }
00132                                 else
00133                                 if (p.toLower() == QObject::tr("synonyms") || p.toLower() == QObject::tr("synonym"))
00134                                 {
00135                                         QStringList syn = o.split(",");
00136                                         for (int i=0; i < syn.size(); ++i)
00137                                         {
00138                                                 QString s2 = syn[i].trimmed().toLower();
00139                                                 if (!Ontology::nodeFamily(s2))
00140                                                 {
00141                                                         family1->synonyms += s2;
00142                                                         Ontology::insertNodeFamily(s2, family1);
00143                                                 }
00144                                         }
00145                                 }
00146                                 else
00147                                 if (p.toLower() == QObject::tr("description"))
00148                                 {
00149                                         family1->description = o;
00150                                 }
00151                                 else
00152                                 if (p.toLower() == QObject::tr("units") || p.toLower() == QObject::tr("unit"))
00153                                 {
00154                                         QStringList lst = o.split(",");
00155                                         if (lst.size() > 1)
00156                                         {
00157                                                 QString property = lst[0];
00158                                                 QStringList unitnames = lst[1].split(" ");
00159                                                 for (int i=0; i < unitnames.size(); ++i)
00160                                                         if (!family1->measurementUnitOptions.contains(Unit(property, unitnames[i].trimmed())))
00161                                                                 family1->measurementUnitOptions += Unit(property, unitnames[i].trimmed());
00162                                         }
00163                                 }
00164                                 else
00165                                 if (p.toLower() == QObject::tr("conditions") || p.toLower() == QObject::tr("condition") ||
00166                                          p.toLower() == QObject::tr("restrictions") || p.toLower() == QObject::tr("restriction"))
00167                                 {
00168                                         family1->restrictions += o.split(",");
00169                                 }
00170                                 else
00171                                 {
00172                                         bool ok;
00173                                         double d = o.toDouble(&ok);
00174                                         if (ok)
00175                                                 family1->numericalAttributes[p.trimmed()] = d;
00176                                         else
00177                                                 family1->textAttributes[p.trimmed()] = o.trimmed();
00178                                 }
00179                         }
00180                 }
00181 
00182                 static void read_connection_triple(void* user_data, raptor_statement* triple) 
00183                 {
00184                         QString s,p,o;
00185                         ConnectionFamily *family1 = 0, *family2 = 0;
00186 
00187                         if (triple->subject->type == RAPTOR_TERM_TYPE_URI)
00188                                 s = QObject::tr((char*)raptor_uri_as_string(triple->subject->value.uri));
00189                         else
00190                         if (triple->subject->type == RAPTOR_TERM_TYPE_LITERAL)
00191                                 s = QObject::tr((char*)(triple->subject->value.literal.string));
00192 
00193                         if (triple->predicate->type == RAPTOR_TERM_TYPE_URI)
00194                                 p = QObject::tr((char*)raptor_uri_as_string(triple->predicate->value.uri));
00195                         else
00196                         if (triple->predicate->type == RAPTOR_TERM_TYPE_LITERAL)
00197                                 p = QObject::tr((char*)(triple->predicate->value.literal.string));
00198 
00199                         if (triple->object->type == RAPTOR_TERM_TYPE_URI)
00200                                 o = QObject::tr((char*)raptor_uri_as_string(triple->object->value.uri));
00201                         else
00202                         if (triple->object->type == RAPTOR_TERM_TYPE_LITERAL)
00203                                 o = QObject::tr((char*)(triple->object->value.literal.string));
00204 
00205                         if (!s.isEmpty()         && !p.isEmpty() && !o.isEmpty())
00206                         {
00207                                 //insert s as new family
00208                                 s = s.toLower();
00209                                 family1 = Ontology::connectionFamily(s);
00210                                 if (!family1)
00211                                 {
00212                                         family1 = new ConnectionFamily(s);
00213                                         Ontology::insertConnectionFamily(s,family1);                                    
00214                                         Ontology::insertConnectionFamily(family1->name(),family1);
00215                                         if (s != family1->name())
00216                                                 Ontology::insertConnectionFamily(s,family1);
00217                                 }
00218 
00219                                 if (!lastReadFamilyNames.contains(family1->name()))
00220                                         lastReadFamilyNames << family1->name();
00221 
00222                                 if (p == QObject::tr("a") || p == QObject::tr("isa") || p == QObject::tr("is a"))  //if isa relationship
00223                                 {
00224                                         o = o.toLower(); 
00225                                         family2 = Ontology::connectionFamily(o);
00226                                         if (!family2)  //insert o as new family
00227                                         {
00228                                                 family2 = new ConnectionFamily(o);
00229                                                 Ontology::insertConnectionFamily(o,family2);
00230                                                 Ontology::insertConnectionFamily(family2->name(),family2);
00231                                                 if (o != family2->name())
00232                                                         Ontology::insertConnectionFamily(o,family2);
00233                                         }
00234                                         family1->setParent(family2);
00235                                         if (!lastReadFamilyNames.contains(family2->name()))
00236                                                 lastReadFamilyNames << family2->name();
00237                                 }
00238                                 else
00239                                 if (p.toLower() == QObject::tr("synonyms"))
00240                                 {
00241                                         QStringList syn = o.split(",");
00242                                         for (int i=0; i < syn.size(); ++i)
00243                                         {
00244                                                 QString s2 = syn[i].trimmed().toLower();
00245                                                 if (!Ontology::connectionFamily(s2))
00246                                                 {
00247                                                         family1->synonyms += s2;
00248                                                         Ontology::insertConnectionFamily(s2, family1);
00249                                                 }
00250                                         }
00251                                 }
00252                                 else
00253                                 if (p.toLower() == QObject::tr("description"))
00254                                 {
00255                                         family1->description = o;
00256                                 }
00257                                 else
00258                                 if (p.toLower() == QObject::tr("units") || p.toLower() == QObject::tr("unit"))
00259                                 {
00260                                         QStringList lst = o.split(",");
00261                                         if (lst.size() > 1)
00262                                         {
00263                                                 QString property = lst[0];
00264                                                 QStringList unitnames = lst[1].split(" ");
00265                                                 for (int i=0; i < unitnames.size(); ++i)
00266                                                         if (!family1->measurementUnitOptions.contains(Unit(property, unitnames[i].trimmed())))
00267                                                                 family1->measurementUnitOptions += Unit(property, unitnames[i].trimmed());
00268                                         }
00269                                 }
00270                                 else
00271                                 if (p.toLower() == QObject::tr("participants") || p.toLower() == QObject::tr("participant"))
00272                                 {
00273                                         QStringList lst = o.split(",");
00274                                         if (lst.size() > 1)
00275                                         {
00276                                                 QString type = lst[0].trimmed();
00277                                                 QString role = lst[1].trimmed();
00278                                                 family1->addParticipant(role, type);
00279                                         }
00280                                 }
00281                                 else
00282                                 if (p.toLower() == QObject::tr("conditions") || p.toLower() == QObject::tr("condition") ||
00283                                          p.toLower() == QObject::tr("restrictions") || p.toLower() == QObject::tr("restriction"))
00284                                 {
00285                                         family1->restrictions += o.split(",");
00286                                 }
00287                                 else
00288                                 {
00289                                         bool ok;
00290                                         double d = o.toDouble(&ok);
00291                                         if (ok)
00292                                                 family1->numericalAttributes[p.trimmed()] = d;
00293                                         else
00294                                                 family1->textAttributes[p.trimmed()] = o.trimmed();
00295                                 }
00296                         }
00297                 }
00298 
00299                 static void parse_rdf_file( void (*callback)(void*, raptor_statement*), const char * filename, const char * format)
00300                 {
00301                         raptor_world *world = NULL;
00302                         raptor_parser* rdf_parser = NULL;
00303                         unsigned char *uri_string;
00304                         raptor_uri *uri, *base_uri;
00305                         world = raptor_new_world();
00306                         rdf_parser = raptor_new_parser(world, format);
00307 
00308                         raptor_parser_set_statement_handler(rdf_parser, NULL, callback);
00309 
00310                         uri_string = raptor_uri_filename_to_uri_string(filename);
00311                         uri = raptor_new_uri(world, uri_string);
00312                         base_uri = raptor_uri_copy(uri);
00313                         raptor_parser_parse_file(rdf_parser, uri, base_uri);
00314                         raptor_free_parser(rdf_parser);
00315                         raptor_free_uri(base_uri);
00316                         raptor_free_uri(uri);
00317                         raptor_free_memory(uri_string);
00318 
00319                         raptor_free_world(world);
00320                 }
00321 
00322                 QStringList Ontology::readNodes(const QString& rdf, const QString& format)
00323                 {
00324                         lastReadFamilyNames.clear();
00325                         parse_rdf_file(&read_node_triple, rdf.toAscii().data(), format.toAscii().data());
00326                         NodeFamily * family = 0;
00327                         QList<NodeFamily*> families;
00328                         for (int i=0; i < lastReadFamilyNames.size(); ++i)
00329                                 if ((family = Ontology::nodeFamily(lastReadFamilyNames[i])) &&
00330                                         !families.contains(family) &&
00331                                         family->parent() == 0)
00332                                         families += family;
00333                         for (int i=0; i < families.size(); ++i)
00334                         {
00335                                 NodeFamily * parent = NodeFamily::cast(families[i]->parent());
00336                                 if (parent)
00337                                 {
00338                                         if (families[i]->description.isEmpty())
00339                                                 families[i]->description = parent->description;
00340                                         if (families[i]->measurementUnitOptions.isEmpty())
00341                                                 families[i]->measurementUnitOptions = parent->measurementUnitOptions;
00342                                         QStringList keys(parent->textAttributes.keys());
00343                                         for (int j=0; j < keys.size(); ++j)
00344                                                 if (!families[i]->textAttributes.contains(keys[j]))
00345                                                         families[i]->textAttributes[ keys[j] ] = parent->textAttributes[ keys[j] ];
00346                                         keys = QStringList(parent->numericalAttributes.keys());
00347                                         for (int j=0; j < keys.size(); ++j)
00348                                                 if (!families[i]->numericalAttributes.contains(keys[j]))
00349                                                         families[i]->numericalAttributes[ keys[j] ] = parent->numericalAttributes[ keys[j] ];
00350                                 }
00351                                 
00352                                 if (!families[i]->measurementUnitOptions.isEmpty())
00353                                         families[i]->measurementUnit = families[i]->measurementUnitOptions.first();
00354                                 families += NodeFamily::cast(families[i]->children());
00355                         }
00356                         return lastReadFamilyNames;
00357                 }
00358 
00359                 QStringList Ontology::readConnections(const QString& rdf, const QString& format)
00360                 {
00361                         lastReadFamilyNames.clear();
00362                         parse_rdf_file(&read_connection_triple, rdf.toAscii().data(), format.toAscii().data());
00363                         ConnectionFamily * family = 0;
00364                         QList<ConnectionFamily*> families;
00365                         for (int i=0; i < lastReadFamilyNames.size(); ++i)
00366                                 if ((family = Ontology::connectionFamily(lastReadFamilyNames[i])) &&
00367                                         !families.contains(family) &&
00368                                         family->parent() == 0)
00369                                         families += family;
00370                         for (int i=0; i < families.size(); ++i)
00371                         {
00372                                 ConnectionFamily * parent = ConnectionFamily::cast(families[i]->parent());
00373                                 if (parent)
00374                                 {
00375                                         if (families[i]->participantRoles().isEmpty())
00376                                         {
00377                                                 QStringList roles = parent->participantRoles();
00378                                                 QStringList types = parent->participantTypes();
00379                                                 for (int j=0; j < roles.size() && j < types.size(); ++j)
00380                                                         families[i]->addParticipant(roles[j],types[j]);
00381                                         }
00382                                         if (families[i]->description.isEmpty())
00383                                                 families[i]->description = parent->description;
00384                                         if (families[i]->measurementUnitOptions.isEmpty())
00385                                                 families[i]->measurementUnitOptions = parent->measurementUnitOptions;
00386                                         QStringList keys(parent->textAttributes.keys());
00387                                         for (int j=0; j < keys.size(); ++j)
00388                                                 if (!families[i]->textAttributes.contains(keys[j]))
00389                                                         families[i]->textAttributes[ keys[j] ] = parent->textAttributes[ keys[j] ];
00390                                         keys = QStringList(parent->numericalAttributes.keys());
00391                                         for (int j=0; j < keys.size(); ++j)
00392                                                 if (!families[i]->numericalAttributes.contains(keys[j]))
00393                                                         families[i]->numericalAttributes[ keys[j] ] = parent->numericalAttributes[ keys[j] ];
00394                                 }
00395                                 if (!families[i]->measurementUnitOptions.isEmpty())
00396                                         families[i]->measurementUnit = families[i]->measurementUnitOptions.first();
00397                                 families += ConnectionFamily::cast(families[i]->children());
00398                         }
00399                         return lastReadFamilyNames;
00400                 }
00401 #else
00402                 QStringList Ontology::readNodes(const QString& rdfFile, const QString& format)
00403                 {
00404                         return QStringList();
00405                 }
00406 
00407                 QStringList Ontology::readConnections(const QString& rdfFile, const QString& format)
00408                 {
00409                         return QStringList();
00410                 }
00411 #endif
00412                 
00413                 void Ontology::cleanup()
00414                 {
00415                         QList<NodeFamily*> nodes = nodeFamilies.values(), visitedNodes;
00416                         QList<ConnectionFamily*> connections = connectionFamilies.values(), visitedConnections;
00417                         
00418                         for (int i=0; i < nodes.size(); ++i)
00419                                 if (nodes[i] && !visitedNodes.contains(nodes[i]))
00420                                 {
00421                                         visitedNodes << nodes[i];
00422                                         delete nodes[i];
00423                                 }
00424                         
00425                         for (int i=0; i < connections.size(); ++i)
00426                                 if (connections[i] && !visitedConnections.contains(connections[i]))
00427                                 {
00428                                         visitedConnections << connections[i];
00429                                         delete connections[i];
00430                                 }
00431 
00432                         nodeFamilies.clear();
00433                         connectionFamilies.clear();
00434                 }
00435 
00436                 QHash<QString, NodeFamily*>  Ontology::nodeFamilies;
00437                 QHash<QString, ConnectionFamily*>  Ontology::connectionFamilies;
00438 }
00439 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines