libSBML C++ API
libSBML 5.8.0 C++ API
|
This section describes the summary of how to implement a package extension for libSBML-5.
(Note that since libSBML-5 is currently in development stage the API described in this documentation may be changed in the future.)
Firstly, an SBMLExtension derived class for your package needs to be implemented based on the steps described in SBMLExtension class.
Secondly, SBase derived classes for your package need to be implemented based on the following steps:
For example, the following elements are defined in the groups package:
For example, the following subelements and attributes are defined in the Group element in the groups package.
subelements
attributes
For example, the following protected data members are defined in Group class ('src/packages/groups/sbml/Group.h'):
class LIBSBML_EXTERN Group : public SBase { protected: std::string mId; std::string mName; ListOfMembers mMembers; .... };
Basically, the attribute data will have one of the types "std::string", "double", "int", or "bool", and the type of the element data will be ListOf derived classes or SBase derived classes.
The data members must be properly initialized in the constructor, and must be properly copied in the copy constructor and assignment operator.
a constructor that accepts three arguments:
For example, this type of constructor of Group class is implemented in 'src/packages/groups/sbml/Group.cpp' as follows:
Group::Group (unsigned int level, unsigned int version, unsigned int pkgVersion) : SBase (level,version) // <-- invokes parent's constructor ,mId("") ,mName("") ,mMembers(level,version,pkgVersion) { // set an SBMLNamespaces derived object (GroupsPkgNamespaces) of //this package. setSBMLNamespacesAndOwn(new GroupsPkgNamespaces(level,version, pkgVersion)); // connects child elements to this element. connectToChild(); }
NOTE
default level, default version, and default pacakge version should be given as default arguments. (This may change in the future release).
the corresponding constructor of the parent class must be properly invoked by using initializer of the constructor.
setSBMLNamespacesAndOwn() function must be invoked with a newly created SBMLNamespaces derived object with the given level, version, and package version.
For example, an instance of the SBase derived object is created by this constructor as follows:
Layout layout(3,1,1);
a constructor that accepts an SBMLNamespaces derived object
For example, this type of constructor of Group class is implemented in 'src/packages/groups/sbml/Group.cpp' as follows: (GroupsPkgNamespaces is the type of SBMLNamespaces derived class for groups package)
Group::Group(GroupsPkgNamespaces* groupsns) : SBase(groupsns) ,mId("") ,mName("") ,mMembers(groupsns) { // set the element namespace of this object setElementNamespace(groupsns->getURI()); // connect child elements to this element connectToChild(); // load pacakge extensions bound with this object (if any) loadPlugins(groupsns); }
NOTE
SBMLNamespaces and its derived class throws an SBMLExtensionException if the given combination is invalid (undefined).
the corresponding constructor of the parent class must be properly invoked by initializer.
setElementNamespace() function must be invoked with the URI of the package in the constructor.
connectToChild() function must be invoked if the element has one or more child elements.
For example, an instance of the SBase derived object is created by this constructor as follows:
try { LayputPkgNamespaces layoutns(3,1,1); Layout layout(&layoutns); } catch (SBMLExtensionException e) { cerr << "Caught " << e.what() << endl; }
NOTE
In the layout extension, additional constructors that accept one or more attributes of the element have been implemented for backward compatibility (support for L2 model). (validation check of the given arguments of attributes are not performed.)
NOTE
corresponding function of the parent class must be invoked in addExpectedAttributes() and readAttributes() functions as follows:
Group::addExpectedAttributes(ExpectedAttributes& attributes) { SBase::addExpectedAttributes(attributes); .... }
void Group::readAttributes (const XMLAttributes& attributes, const ExpectedAttributes& expectedAttributes) { SBase::readAttributes(attributes,expectedAttributes); ... }
(SBase class is a parent of Group class.)
the following attributes don't need to be added in the addExpectedAttributes() function because they are added in SBase::addExpectedAttributes() function.
createObject()
writeElements()
hasRequiredElements()
setSBMLDocument()
enablePackageInternal()
NOTE
corresponding function of the parent class must be invoked in writeElements(), setSBMLDocument(), and enablePackageInternal() functions
"src/packages/groups/sbml/{Group,Member}.{h,cpp}" are simple example files in which these functions are implemented.
NOTE
For example, this function is implemented in the following top-level elements:
SBMLDocument::enableDefaultNS(const std::string& package, bool flag)
setId()
getId()
isSetId()
NOTE
Basically, implementation of these functions are almost the same between elements defining the 'id' attribute
setId() function can be easily implemented as follows (one line):
return SyntaxChecker::checkAndSetSId(id,mId);
setName()
getName()
isSetName()
NOTE
loadPlugins() doesn't need to be invoked in an abstract class.
For example, getMember(), addMember(), getNumMembers(), createMember(), removeMember() and etc. are implemented in Group class of the groups package.
NOTE
when implementing setXXXX(const XXXX&) / addXXXX(const XXXX&) functions that set/add the given SBase derived object, the following check should be done for the given object:
check if the given object is not NULL
check if the SBML Level, Version, and Package Version of the given object matches those of target element
one of status codes, which is defined in "src/common/operationReturnValues.h" should be returned based on the result of functions except for getter functions and functions returning a bool value
In setXXXX(const XXXX&) function, connectToParent() function must be invoked if the given object is valid.
(for detail, please check existing implementation such as setKineticLaw() function in "src/sbml/Reaction.cpp")
Thirdly, SBasePlugin derived classes for the pacakge needs to be implemented.
For example, the following SBML elementes are extended by groups and layout packages, respectively:
groups package
layout package
For example, to extend the identified classes, the following SBasePlugin derived classes are newly implemnted in the groups and layout packages:
groups
NOTE
Package developers can use existing SBMLDocumentPlugin class as-is for extending the SBMLDocument class if only 'required' attribute is added the class in their packages, otherwise package developers must implement a new SBMLDocumentPlugin derived class for extending the SBMLDocument class.
Since the both of groups and layout packages require only 'required' attribute for extending the SBMLDocument class, the SBMLDocumentPlugin is used as-is for the packages.
Basically, the attribute data will have one of the types "std::string", "double", "int", or "bool", and the type of the element data will be ListOf derived classes or SBase derived classes.
The additional data members must be properly initialized in the constructor, and must be properly copied in the copy constructor and assignment operator.
For example, the following data member is defined in the GroupsModelPlugin class (in GroupsModelPlugin.h):
ListOfGroups mGroups;
Constructor
SBasePlugin(const std::string& uri, const std::string &prefix)
Copy Constructor
Assignment operator
clone() function
Basically, clone() function is implemented by using the copy constructor.
NOTE
'src/extension/SBMLDocumentPlugin.{h,cpp} is a simple example files in which these functions are implemented.
NOTE
'src/packages/groups/extension/GroupsModelPlugin.{h,cpp}' and 'src/packages/layout/extension/LayoutModelPlugin.{h,cpp}' are example files in which the functions are implemented.
NOTE
Currently, no example files implementing this function
For example, the following manipulation functions are implemented in LayoutModelPlugin class (a class for the extension of the model element in layout package) for manipulating the additional <listOfLayouts> element in the list element:
Similarly, the following manipulation functions are implemented in GroupsModelPlugin class (a class for the extension of the model element in groups package) for manipulating the additional <listOfGroups> element in the list element:
A header file in which forward declarations for all classes defined in the package extension should be implemented.
For example, please see "src/common/sbmlfwd.h" (forward declaration of SBML Core), "src/packages/groups/common/groupsfwd.h" (forward declaration of Groups package), and "src/packages/layout/common/layoutfwd.h" (forward declaration of Layout package)
A header file in which all SBML types defined in the extension should be implemented. For example, please see "src/packages/groups/common/GroupsExtensionTypes.h" of the groups extension and "src/packages/layout/common/LayoutExtensionTypes.h" of the layout extension.
NOTE
A new package extension can be implemented and built outside the source tree of libSBML. So, this step is not mandatory if you don't want to import your package extension into the source tree of libSBML.
USE_%PACKAGE_NAME%% macro variable needs to be defined in the following files:
(%PACKAGE_NAME%% is a place holder of the package name. For example, USE_LAYOUT is defined for the layout package.)
NOTE
A new package extension can be implemented and built outside the source tree of libSBML. So, this step is not mandatory if you don't want to import your package extension into the source tree of libSBML.
(The following example configuration is that of groups extension)
Add –enable-XXXX
dnl ------------------------------------------------------- dnl Groups extension dnl ------------------------------------------------------- AC_ARG_ENABLE([groups], AC_HELP_STRING([--enable-groups@<:@=ARG@:>@], [Build the SBML groups extension (default=no)]), [enable_groups=$enableval], [enable_groups=no]) if test "$enable_group" != no; then AC_DEFINE([USE_GROUPS], 1, [Define to 1 to build the SBML groups extension.]) AC_SUBST(USE_GROUPS, 1) fi
Add AC_CONFIG_FILES for additional Makefile.in files
AC_CONFIG_FILES([src/packages/groups/Makefile]) AC_CONFIG_FILES([src/packages/groups/common/Makefile]) AC_CONFIG_FILES([src/packages/groups/extension/Makefile]) AC_CONFIG_FILES([src/packages/groups/sbml/Makefile])
Add the code for noticing the enabled package
if test "$enable_groups" != "no" ; then echo " Using groups extension = yes" fi
Run a shell script "autogen.sh" in the top directory of the libsbml-5 as follows (for updating configure script):
% ./autogen.sh
Add the name of package to 'subdirs' variable based on existing code.
Currently, "src/packages/groups" (groups package) and "src/packages/layout" (layout package) exist in the directory.
common
common header and/or class files (e.g. sbmlfwd.h) are located
extension
SBMLExtension and SBasePlugin derived classes of the package extension are located
sbml
SBase derived classes of the package extension are located.
util (if needed)
Utility class files are located (e.g. LayoutAnnotation.{h,cpp} in layout package).
other directories (if needed)