COPASI API  4.16.103
CRDFGraphConverter.cpp
Go to the documentation of this file.
1 // Begin CVS Header
2 // $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/MIRIAM/CRDFGraphConverter.cpp,v $
3 // $Revision: 1.12 $
4 // $Name: $
5 // $Author: shoops $
6 // $Date: 2011/05/24 16:32:37 $
7 // End CVS Header
8 
9 // Copyright (C) 2011 - 2010 by Pedro Mendes, Virginia Tech Intellectual
10 // Properties, Inc., University of Heidelberg, and The University
11 // of Manchester.
12 // All rights reserved.
13 
14 // Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
15 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
16 // and The University of Manchester.
17 // All rights reserved.
18 
19 #include "copasi.h"
20 
21 #include "CRDFGraphConverter.h"
22 #include "CRDFParser.h"
23 #include "CRDFWriter.h"
24 #include "CRDFGraph.h"
25 #include "CRDFUtilities.h"
26 
28 
29 // static
30 CRDFGraphConverter::sChange CRDFGraphConverter::SBML2CopasiChanges[] =
31 {
32  {
34  {
36  }
37  },
38  {
40  {
42  }
43  },
44  {
46  {
48  }
49  },
50  {
52  {
54  }
55  },
56  {
58  {
60  }
61  },
62  {
64  {
66  }
67  },
68  {
70  {
72  }
73  },
74  {
76  {
78  }
79  },
80  {
82  {
84  }
85  },
86  {
88  {
90  }
91  },
92  {
94  {
96  }
97  },
98  {
100  {
102  }
103  },
104  {
106  {
108  },
109  },
110  {
112  {
114  }
115  }
116 };
117 
118 // static
119 bool CRDFGraphConverter::SBML2Copasi(std::string & XML)
120 {
121  // Fix the the broken SBML RDF
122  if (CRDFUtilities::fixSBMLRdf(XML))
124 
125  // Create the RDF graph
126  CRDFGraph * pGraph = CRDFParser::graphFromXml(XML);
127 
128  if (pGraph == NULL)
129  return false;
130 
131  // Convert the graph.
132  bool success = convert(pGraph, SBML2CopasiChanges);
133 
134  // Serialize the graph
135  pGraph->clean();
136  pGraph->updateNamespaces();
137 
138  XML = CRDFWriter::xmlFromGraph(pGraph);
139 
140  if (pGraph != NULL)
141  {
142  delete pGraph;
143  pGraph = NULL;
144  }
145 
146  // It is possible that the graph is still corrupt due secondary errors.
147  // Another parse and write should take care of this.
148  size_t Size = CCopasiMessage::size();
149 
150  pGraph = CRDFParser::graphFromXml(XML);
151 
152  if (pGraph == NULL)
153  return false;
154 
155  XML = CRDFWriter::xmlFromGraph(pGraph);
156 
157  if (pGraph != NULL)
158  {
159  delete pGraph;
160  pGraph = NULL;
161  }
162 
163  // Remove error messages created by the second parse as these are secondary.
164  while (CCopasiMessage::size() > Size)
166 
167  return success;
168 }
169 
170 // static
172 {
173  bool success = true;
174 
175  std::set< CRDFTriplet> Triplets;
176  std::set< CRDFTriplet>::iterator it;
177  std::set< CRDFTriplet>::iterator end;
178 
179  const sChange * pChange = changes;
180 
181  // We iterate over each predicate which needs to be changed.
182  for (; pChange->Source != CRDFPredicate::end; ++pChange)
183  {
184  std::set< CRDFTriplet > Failed;
185 
186  // Create the new path
187  CRDFPredicate::Path NewPath;
188  const CRDFPredicate::ePredicateType * pNewPath = pChange->Target;
189 
190  while (*pNewPath != CRDFPredicate::end)
191  NewPath.push_back(*pNewPath++);
192 
193  // Each change may break the triplets, i.e. we need to refresh every time
194  while ((Triplets = pGraph->getTriplets(pChange->Source, false)).size() > Failed.size())
195  {
196  // Skip all failed triplets
197  for (it = Triplets.begin(), end = Triplets.end(); it != end; ++it)
198  if (Failed.find(*it) == Failed.end())
199  break;
200 
201  if (!convert(pGraph, *it, NewPath))
202  {
203  Failed.insert(*it);
204  success = false;
205  }
206  }
207  }
208 
209  return success;
210 }
211 
212 // static
214  const CRDFTriplet & triplet,
215  const CRDFPredicate::Path & newPath)
216 {
217  CRDFPredicate::Path CurrentPath = triplet.pObject->getPath();
218 
219  size_t SubPathIndex = C_INVALID_INDEX;
220 
221  while (SubPathIndex == C_INVALID_INDEX && SubPathIndex > 0)
222  {
223  // We differ at least at the final predicate.
224  CurrentPath.pop_back();
225  SubPathIndex = CRDFPredicate::getSubPathIndex(newPath, CurrentPath);
226  }
227 
228  if (SubPathIndex == 0)
229  return false;
230 
231  CurrentPath = triplet.pObject->getPath();
232 
233  bool success = true;
234 
235  CRDFTriplet Triplet;
236 
237  if (CurrentPath.size() < newPath.size())
238  {
239  // We need to create the additional node pointed to by newPath[SubPathIndex]
240  // Verify that the node to be created is a blank node.
242  CRDFPredicate::getAllowedLocationList(newPath[SubPathIndex]);
243  CRDFPredicate::AllowedLocationList::const_iterator it = List.begin();
244  CRDFPredicate::AllowedLocationList::const_iterator end = List.end();
245 
246  for (; it != end; ++it)
247  {
248  if (it->Type == CRDFObject::BLANK_NODE &&
249  CRDFPredicate::getSubPathIndex(newPath, it->Location))
250  break;
251  }
252 
253  if (it == end)
254  return false;
255 
256  // We are now sure that the new predicate points to a blank node.
257  CRDFObject Object;
259  Object.setBlankNodeId(pGraph->generatedNodeId());
260 
261  Triplet = pGraph->addTriplet(triplet.pSubject->getSubject(),
262  CRDFPredicate::getURI(newPath[SubPathIndex]),
263  Object);
264 
265  // We need to address the issue when a bag has to be moved.
266  if (Triplet)
267  {
268  if (triplet.pObject->isBagNode())
269  {
270  std::set< CRDFTriplet> Triplets = triplet.pObject->getDescendantsWithPredicate(CRDFPredicate::rdf_li);
271 
272  if (Triplets.size() == 0)
273  {
274  pGraph->removeTriplet(Triplet.pSubject, Triplet.Predicate, Triplet.pObject);
275 
276  return false;
277  }
278 
279  // Bagify the node.
280  CRDFObject Object;
282  Object.setResource("http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag", false);
283  pGraph->addTriplet(Triplet.pObject->getSubject(), CRDFPredicate(CRDFPredicate::rdf_type), Object);
284 
285  // Now we move each li element with the current predicate
286  std::set< CRDFTriplet>::iterator it = Triplets.begin();
287  std::set< CRDFTriplet>::iterator end = Triplets.end();
288 
289  for (; it != end; ++it)
290  {
291  CRDFObject Object;
293  Object.setBlankNodeId(pGraph->generatedNodeId());
294 
295  CRDFTriplet LiTriplet = pGraph->addTriplet(Triplet.pObject->getSubject(),
297  Object);
298 
299  if (LiTriplet)
300  {
301  success &= LiTriplet.pObject->addEdge(triplet.Predicate, it->pObject);
302  it->pSubject->removeEdge(CRDFPredicate(CRDFPredicate::rdf_li), it->pObject);
303  }
304  else
305  {
306  success = false;
307  }
308  }
309 
310  // We have handled the triplet it can be removed from the graph.
311  pGraph->removeTriplet(triplet.pSubject, triplet.Predicate, triplet.pObject);
312 
313  return success;
314  }
315  else
316  {
317  Triplet = pGraph->moveTriplet(Triplet.pObject, triplet);
318  }
319  }
320  }
321  else if (CurrentPath.size() > newPath.size())
322  {
323  // TODO This needs to be implemented
324  // Removing an edge will always result in loosing information!
325  }
326  else
327  {
328  // We just have to rename the predicate
329  success &= triplet.pSubject->addEdge(newPath[SubPathIndex], triplet.pObject);
330  triplet.pSubject->removeEdge(CurrentPath[SubPathIndex], triplet.pObject);
331 
332  if (success)
333  {
334  Triplet = triplet;
335  Triplet.Predicate = newPath[SubPathIndex];
336  }
337  }
338 
339  if (!Triplet)
340  return false;
341 
342  // Check whether we are finished
343  if (SubPathIndex == newPath.size() - 1)
344  return success;
345 
346  return convert(pGraph, Triplet, newPath);
347 }
static bool convert(CRDFGraph *pGraph, const sChange *changes)
static unsigned C_INT32 fixSBMLRdf(std::string &rdfXml)
static sChange SBML2CopasiChanges[]
void removeTriplet(CRDFNode *pSubject, const CRDFPredicate &predicate, CRDFNode *pObject)
Definition: CRDFGraph.cpp:277
void updateNamespaces()
Definition: CRDFGraph.cpp:558
std::set< CRDFTriplet > getDescendantsWithPredicate(const CRDFPredicate &predicate) const
Definition: CRDFNode.cpp:398
CRDFNode * pSubject
Definition: CRDFTriplet.h:38
const CRDFSubject & getSubject() const
Definition: CRDFNode.cpp:69
std::vector< sAllowedLocation > AllowedLocationList
bool isBagNode() const
Definition: CRDFNode.cpp:423
#define C_INVALID_INDEX
Definition: copasi.h:222
CRDFPredicate::ePredicateType Source
CRDFTriplet moveTriplet(CRDFNode *pNewSubject, const CRDFTriplet &triplet)
Definition: CRDFGraph.cpp:334
void setType(const eObjectType &type)
Definition: CRDFObject.cpp:82
#define MCSBML
CRDFTriplet addTriplet(const CRDFSubject &subject, const CRDFPredicate &predicate, const CRDFObject &object)
Definition: CRDFGraph.cpp:141
const std::set< CRDFTriplet > & getTriplets() const
Definition: CRDFGraph.cpp:434
CRDFPredicate::Path getPath() const
Definition: CRDFNode.cpp:110
static size_t size()
static size_t getSubPathIndex(const Path &fullPath, const Path &currentPath)
static const AllowedLocationList & getAllowedLocationList(const ePredicateType &predicate)
CRDFPredicate Predicate
Definition: CRDFTriplet.h:40
void removeEdge(const CRDFPredicate &predicate, CRDFNode *pObject)
Definition: CRDFNode.cpp:361
void setResource(const std::string &resource, const bool &isLocal)
Definition: CRDFObject.cpp:88
static bool SBML2Copasi(std::string &XML)
static CCopasiMessage getLastMessage()
const std::string & getURI() const
void clean()
Definition: CRDFGraph.cpp:511
void setBlankNodeId(const std::string &blankNodeId)
Definition: CRDFObject.cpp:100
CRDFPredicate::ePredicateType Target[4]
std::string generatedNodeId(const std::string &existingId="")
Definition: CRDFGraph.cpp:380
CRDFNode * pObject
Definition: CRDFTriplet.h:42
static CRDFGraph * graphFromXml(const std::string &xml)
Definition: CRDFParser.cpp:30
CRDFTriplet addEdge(const CRDFPredicate &predicate, CRDFNode *pObject)
Definition: CRDFNode.cpp:321
std::vector< ePredicateType > Path
Definition: CRDFPredicate.h:91
static std::string xmlFromGraph(const CRDFGraph *pGraph)
Definition: CRDFWriter.cpp:26