1 /*
2 * ****************************************************************************
3 * This file is part of libNUML. Please visit http://code.google.com/p/numl/for more
4 * information about NUML, and the latest version of libNUML.
5 * Copyright (c) 2013 The University of Manchester.
6 *
7 * This library is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation. A copy of the license agreement is
10 * provided in the file named "LICENSE.txt" included with this software
11 * distribution and also available online as http://www.gnu.org/licenses/lgpl.html
12 *
13 * Contributors:
14 * Joseph O. Dada, The University of Manchester - initial API and implementation
15 * ****************************************************************************
16 **/
17
18
19 #include <limits>
20
21
22 #include <sbml/xml/XMLNode.h>
23 #include <sbml/xml/XMLAttributes.h>
24 #include <sbml/xml/XMLInputStream.h>
25 #include <sbml/xml/XMLOutputStream.h>
26
27
28 #include <numl/NUMLDocument.h>
29 #include <numl/common/operationReturnValues.h>
30
31 #include <numl/NUMLVisitor.h>
32 #include <numl/NUMLError.h>
33 #include <numl/OntologyTerm.h>
34
35 using namespace std;
36
37 LIBNUML_CPP_NAMESPACE_BEGIN
38
OntologyTerm(unsigned int level,unsigned int version)39 OntologyTerm::OntologyTerm (unsigned int level, unsigned int version) :
40 NMBase ( level, version )
41 , mId ( "" )
42 , mTerm ( "" )
43 , mSourceTermId ( "" )
44 , mOntologyURI ( "" )
45 {
46 if (!hasValidLevelVersionNamespaceCombination())
47 throw NUMLConstructorException();
48 }
49
50
OntologyTerm(NUMLNamespaces * numlns)51 OntologyTerm::OntologyTerm (NUMLNamespaces *numlns) :
52 NMBase ( numlns )
53 ,mId ( "" )
54 ,mTerm ( "" )
55 ,mSourceTermId ( "" )
56 ,mOntologyURI ( "" )
57 {
58 if (!hasValidLevelVersionNamespaceCombination())
59 throw NUMLConstructorException();
60 }
61
62 /*
63 * Accepts the given NUMLVisitor.
64 *
65 * @return the result of calling <code>v.visit()</code>, which indicates
66 * whether or not the Visitor would like to visit the NUML Doc's next
67 * OntologyTerm (if available).
68 */
69 bool
accept(NUMLVisitor & v) const70 OntologyTerm::accept (NUMLVisitor& v) const
71 {
72 return v.visit(*this);
73 }
74
75
76 /*
77 * @return a (deep) copy of this OntologyTerm.
78 */
79 OntologyTerm*
clone() const80 OntologyTerm::clone () const
81 {
82 return new OntologyTerm(*this);
83 }
84
85 /*
86 * Sets the id of this NUML object to a copy of sid.
87 */
88 int
setId(const std::string & sid)89 OntologyTerm::setId (const std::string& sid)
90 {
91
92 if (!(LIBSBML_CPP_NAMESPACE_QUALIFIER SyntaxChecker::isValidSBMLSId(sid)))
93 {
94 return LIBNUML_INVALID_ATTRIBUTE_VALUE;
95 }
96 else
97 {
98 mId = sid;
99 return LIBNUML_OPERATION_SUCCESS;
100 }
101 }
102
103
104 /*
105 * Sets the term attribute of this NUML object to a copy of term.
106 */
setTerm(const std::string & term)107 int OntologyTerm::setTerm(const std::string& term) {
108 mTerm = term;
109 return LIBNUML_OPERATION_SUCCESS;
110
111 }
112
113
114 /*
115 * Sets the ontologyURI attribute of this NUML object to a copy of ontologyURI.
116 */
setOntologyURI(const std::string & ontologyURI)117 int OntologyTerm::setOntologyURI(const std::string& ontologyURI) {
118 mOntologyURI = ontologyURI;
119 return LIBNUML_OPERATION_SUCCESS;
120
121 }
122
123
124 /*
125 * Sets the sourceTermId attribute of this NUML object to a copy of sourceTermId.
126 */
setSourceTermId(const std::string & sourceTermId)127 int OntologyTerm::setSourceTermId(const std::string& sourceTermId) {
128 mSourceTermId = sourceTermId;
129 return LIBNUML_OPERATION_SUCCESS;
130
131 }
132
133 /*
134 * @return the id of this NUML object.
135 */
136 const string&
getId() const137 OntologyTerm::getId () const
138 {
139 return mId;
140 }
141
142
143 /*
144 * @return the term of this NUML object.
145 */
146 const string&
getTerm() const147 OntologyTerm::getTerm () const
148 {
149 return mTerm;
150 }
151
152 /*
153 * @return the sourceTermId of this NUML object.
154 */
155 const string&
getSourceTermId() const156 OntologyTerm::getSourceTermId () const
157 {
158 return mSourceTermId;
159 }
160
161 /*
162 * @return the ontologyURI of this NUML object.
163 */
164 const string&
getOntologyURI() const165 OntologyTerm::getOntologyURI () const
166 {
167 return mOntologyURI;
168 }
169
170 /* constructor for validators */
OntologyTerm()171 OntologyTerm::OntologyTerm() :
172 NMBase()
173 {
174 }
175
176
177 /*
178 * Destroys this OntologyTerm.
179 */
~OntologyTerm()180 OntologyTerm::~OntologyTerm ()
181 {
182 }
183
184 /*
185 * @return the NUMLTypeCode_t of this NUML object or NUML_UNKNOWN
186 * (default).
187 *
188 * @see getElementName()
189 */
190 NUMLTypeCode_t
getTypeCode() const191 OntologyTerm::getTypeCode () const
192 {
193 return NUML_ONTOLOGYTERM;
194 }
195
196
197 /*
198 * @return the name of this element ie "ontologyTerm".
199 */
200 const string&
getElementName() const201 OntologyTerm::getElementName () const
202 {
203 static const string ontologyTerm = "ontologyTerm";
204 return ontologyTerm;
205 }
206
207
208 /*
209 * Subclasses should override this method to read values from the given
210 * XMLAttributes set into their specific fields. Be sure to call your
211 * parents implementation of this method as well.
212 */
213 void
readAttributes(const LIBSBML_CPP_NAMESPACE_QUALIFIER XMLAttributes & attributes)214 OntologyTerm::readAttributes (const LIBSBML_CPP_NAMESPACE_QUALIFIER XMLAttributes& attributes)
215 {
216 NMBase::readAttributes(attributes);
217
218 const unsigned int level = getLevel ();
219 const unsigned int version = getVersion();
220
221 std::vector<std::string> expectedAttributes;
222 expectedAttributes.clear();
223 expectedAttributes.push_back("metaid");
224 expectedAttributes.push_back("id");
225 expectedAttributes.push_back("term");
226 expectedAttributes.push_back("sourceTermId");
227 expectedAttributes.push_back("ontologyURI");
228
229 // check that all attributes are expected
230 for (int i = 0; i < attributes.getLength(); i++)
231 {
232 std::vector<std::string>::const_iterator end = expectedAttributes.end();
233 std::vector<std::string>::const_iterator begin = expectedAttributes.begin();
234
235 std::string name = attributes.getName(i);
236 if (std::find(begin, end, name) == end)
237 {
238 logUnknownAttribute(name, level, version, "<ontologyTerm>");
239 }
240 }
241
242 const string id = "id";
243 bool assigned = attributes.readInto(id, mId, getErrorLog(), true);
244 if (assigned && mId.size() == 0)
245 {
246 logEmptyString(id, level, version, "<ontologyTerm>");
247 }
248 if (!LIBSBML_CPP_NAMESPACE_QUALIFIER SyntaxChecker::isValidSBMLSId(mId)) logError(NUMLInvalidIdSyntax);
249
250 attributes.readInto("term", mTerm);
251 attributes.readInto("sourceTermId", mSourceTermId);
252 attributes.readInto("ontologyURI", mOntologyURI);
253 }
254
255
256 /*
257 * Subclasses should override this method to write their XML attributes
258 * to the XMLOutputStream. Be sure to call your parents implementation
259 * of this method as well.
260 */
261 void
writeAttributes(LIBSBML_CPP_NAMESPACE_QUALIFIER XMLOutputStream & stream) const262 OntologyTerm::writeAttributes (LIBSBML_CPP_NAMESPACE_QUALIFIER XMLOutputStream& stream) const
263 {
264 NMBase::writeAttributes(stream);
265
266 //const unsigned int level = getLevel ();
267 //const unsigned int version = getVersion();
268
269 stream.writeAttribute("id", mId);
270 stream.writeAttribute("term", mTerm);
271 stream.writeAttribute("sourceTermId", mSourceTermId);
272 stream.writeAttribute("ontologyURI", mOntologyURI);
273
274 }
275
276
277
278
279 /*
280 * @return a (deep) copy of this OntologyTerms.
281 */
282 OntologyTerms*
clone() const283 OntologyTerms::clone () const
284 {
285 return new OntologyTerms(*this);
286 }
287
288
289 /*
290 * @return the NUMLTypeCode_t of NUML objects contained in this OntologyTerms or
291 * NUML_UNKNOWN (default).
292 * @return the annotation of this NUML object by string.
293 */
294 /* TODO std::string
295 NMBase::getAnnotationString ()
296 {
297 return XMLNode::convertXMLNodeToString(getAnnotation());
298 }*/
299
300 NUMLTypeCode_t
getItemTypeCode() const301 OntologyTerms::getItemTypeCode () const
302 {
303 return NUML_ONTOLOGYTERM;
304 }
305
306
307 /*
308 * @return the name of this element ie "ontologyTerms".
309 */
310 const string&
getElementName() const311 OntologyTerms::getElementName () const
312 {
313 static const string name = "ontologyTerms";
314 return name;
315 }
316
317
318 /* return nth item in list */
319 OntologyTerm *
get(unsigned int n)320 OntologyTerms::get(unsigned int n)
321 {
322 return static_cast<OntologyTerm*>(NUMLList::get(n));
323 }
324
325
326 /* return nth item in list */
327 const OntologyTerm *
get(unsigned int n) const328 OntologyTerms::get(unsigned int n) const
329 {
330 return static_cast<const OntologyTerm*>(NUMLList::get(n));
331 }
332
333
334 /**
335 * Used by OntologyTerms::get() to lookup an NMBase based by its id.
336 */
337 struct IdEqS
338 {
339 const string& id;
340
IdEqSIdEqS341 IdEqS (const string& id) : id(id) { }
operator ()IdEqS342 bool operator() (NMBase* sb)
343 { return static_cast <OntologyTerm *> (sb)->getId() == id; }
344 };
345
346
347 /* return item by id */
348 OntologyTerm*
get(const std::string & sid)349 OntologyTerms::get (const std::string& sid)
350 {
351 return const_cast<OntologyTerm*>(
352 static_cast<const OntologyTerms&>(*this).get(sid) );
353 }
354
355
356 /* return item by id */
357 const OntologyTerm*
get(const std::string & sid) const358 OntologyTerms::get (const std::string& sid) const
359 {
360 vector<NMBase*>::const_iterator result;
361
362 result = find_if( mItems.begin(), mItems.end(), IdEqS(sid) );
363 return (result == mItems.end()) ? 0 : static_cast <OntologyTerm*> (*result);
364 }
365
366
367 /* Removes the nth item from this list */
368 OntologyTerm*
remove(unsigned int n)369 OntologyTerms::remove (unsigned int n)
370 {
371 return static_cast<OntologyTerm*>(NUMLList::remove(n));
372 }
373
374
375 /* Removes item in this list by id */
376 OntologyTerm*
remove(const std::string & sid)377 OntologyTerms::remove (const std::string& sid)
378 {
379 NMBase* item = 0;
380 vector<NMBase*>::iterator result;
381
382 result = find_if( mItems.begin(), mItems.end(), IdEqS(sid) );
383
384 if (result != mItems.end())
385 {
386 item = *result;
387 mItems.erase(result);
388 }
389
390 return static_cast <OntologyTerm*> (item);
391 }
392
393 /*
394 * @return the ordinal position of the element with respect to its siblings
395 * or -1 (default) to indicate the position is not significant.
396 */
397 int
getElementPosition() const398 OntologyTerms::getElementPosition () const
399 {
400 return 1;
401 }
402
403
404 /*
405 * @return the NUML object corresponding to next XMLToken in the
406 * XMLInputStream or NULL if the token was not recognized.
407 */
408 NMBase*
createObject(LIBSBML_CPP_NAMESPACE_QUALIFIER XMLInputStream & stream)409 OntologyTerms::createObject (LIBSBML_CPP_NAMESPACE_QUALIFIER XMLInputStream& stream)
410 {
411 const string& name = stream.peek().getName();
412 NMBase* object = 0;
413
414 if (name == "ontologyTerm")
415 {
416 try
417 {
418 object = new OntologyTerm(getNUMLNamespaces());
419 }
420 catch (NUMLConstructorException*)
421 {
422 object = new OntologyTerm(NUMLDocument::getDefaultLevel(), NUMLDocument::getDefaultVersion());
423 }
424 catch ( ... )
425 {
426 object = new OntologyTerm(NUMLDocument::getDefaultLevel(), NUMLDocument::getDefaultVersion());
427 }
428
429 if (object) mItems.push_back(object);
430 }
431
432 return object;
433 }
434
435 LIBNUML_CPP_NAMESPACE_END
436