![]() |
TinkerCell Core 1.0
TinkerCell's Core library providing all basic functionalities
|
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