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