libSBML C API
libSBML 5.8.0 C API
|
The core component of SBML's package extension.
SBMLExtension class (abstract class) is a core component of package extension which needs to be extended by package developers. The class provides functions for getting common attributes of package extension (e.g., package name, package version, and etc.), functions for adding (registering) each instantiated SBasePluginCreator object, and a static function (defined in each SBMLExtension extended class) for initializing/registering the package extension when the library of the package is loaded.
Package developers must implement an SBMLExtension extended class for their packages (e.g. GroupsExtension class is implemented for groups extension). The extended class is implemented based on the following steps:
(NOTE: "src/pacakges/groups/extension/GroupsExtension.{h,cpp}" and "src/pacakges/layout/extension/LayoutExtension.{h,cpp}" are example files in which SBMLExtension derived classes are implemented)
Define the following static functions in the extended class: (examples of groups extension are shown respectively)
A string of package name (label) (The function name must be "getPackageName".)
const std::string& GroupsExtension::getPackageName () { static const std::string pkgName = "groups"; return pkgName; }
Methods returning an integer of Default SBML level, version, and package version (The method names must be "getDefaultLevel()", "getDefaultVersion()", and "getDefaultPackageVersion()" respectively.)
unsigned int GroupsExtension::getDefaultLevel() { return 3; } unsigned int GroupsExtension::getDefaultVersion() { return 1; } unsigned int GroupsExtension::getDefaultPackageVersion() { return 1; }
Methods returning Strings that represent the URI of packages
const std::string& GroupsExtension::getXmlnsL3V1V1 () { static const std::string xmlns = "http://www.sbml.org/sbml/level3/version1/groups/version1"; return xmlns; }
Strings that represent the other URI needed in this package (if any)
Override the following pure virtual functions
virtual const std::string& getName () const =0
. This function returns the name of the package (e.g., "layout", "groups"). virtual unsigned int getLevel (const std::string &uri) const =0
. This function returns the SBML level with the given URI of this package. virtual unsigned int getVersion (const std::string &uri) const =0
. This function returns the SBML version with the given URI of this package. virtual unsigned int getPackageVersion (const std::string &uri) const =0
. This function returns the package version with the given URI of this package. virtual unsigned int getURI (unsigned int sbmlLevel, unsigned int sbmlVersion, unsigned int pkgVersion) const =0
. This function returns the URI (namespace) of the package corresponding to the combination of the given sbml level, sbml version, and pacakege version virtual SBMLExtension* clone () const = 0
. This function creates and returns a deep copy of this derived object. For example, the above functions are overridden in the groups package ("src/packages/groups/extension/GroupsExtension.cpp") as follows:
const std::string& GroupsExtension::getName() const { return getPackageName(); } unsigned int GroupsExtension::getLevel(const std::string &uri) const { if (uri == getXmlnsL3V1V1()) { return 3; } return 0; } unsigned int GroupsExtension::getVersion(const std::string &uri) const { if (uri == getXmlnsL3V1V1()) { return 1; } return 0; } unsigned int GroupsExtension::getPackageVersion(const std::string &uri) const { if (uri == getXmlnsL3V1V1()) { return 1; } return 0; } const std::string& GroupsExtension::getURI(unsigned int sbmlLevel, unsigned int sbmlVersion, unsigned int pkgVersion) const { if (sbmlLevel == 3) { if (sbmlVersion == 1) { if (pkgVersion == 1) { return getXmlnsL3V1V1(); } } } static std::string empty = ""; return empty; } GroupsExtension* GroupsExtension::clone () const { return new GroupsExtension(*this); }
Constructor, copy Constructor, and destructor also must be overridden if additional data members are defined in the derived class.
Define typedef and template instantiation code for the package specific SBMLExtensionNamespaces template class
typedef for the package specific SBMLExtensionNamespaces template class
For example, the typedef for GroupsExtension (defined in the groups package) is implemented in GroupsExtension.h as follows:
// GroupsPkgNamespaces is derived from the SBMLNamespaces class and used when creating an object of // SBase derived classes defined in groups package. typedef SBMLExtensionNamespaces<GroupsExtension> GroupsPkgNamespaces;
template instantiation code for the above typedef definition in the implementation file (i.e., *.cpp file).
For example, the template instantiation code for GroupsExtension is implemented in GroupsExtension.cpp as follows:
// Instantiate SBMLExtensionNamespaces<GroupsExtension> (GroupsPkgNamespaces) for DLL. template class LIBSBML_EXTERN SBMLExtensionNamespaces<GroupsExtension>;
The SBMLExtensionNamespaces template class is a derived class of SBMLNamespaces and can be used as an argument of constructors of SBase derived classes defined in the package extensions. For example, a GroupsPkgNamespaces object can be used when creating a group object as follows:
GroupPkgNamespaces gpns(3,1,1); // The arguments are SBML Level, SBML Version, and Groups Package Version. Group g = new Group(&gpns); // Creates a group object of L3V1 Groups V1.
Also, the GroupsPkgNamespaces object can be used when creating an SBMLDocument object with the groups package as follows:
GroupsPkgNamespaces gpns(3,1,1); SBMLDocument* doc; doc = new SBMLDocument(&gnps); // Creates an SBMLDocument of L3V1 with Groups V1.
Override the following pure virtual function which returns the SBMLNamespaces derived object
virtual SBMLNamespaces* getSBMLExtensionNamespaces (const std::string &uri) const =0
For example, the function is overridden in GroupsExtension class as follows:
SBMLNamespaces* GroupsExtension::getSBMLExtensionNamespaces(const std::string &uri) const { GroupsPkgNamespaces* pkgns = NULL; if ( uri == getXmlnsL3V1V1()) { pkgns = new GroupsPkgNamespaces(3,1,1); } return pkgns; }
Define an enum type for representing the typecode of elements (SBase extended classes) defined in the package extension
For example, SBMLGroupsTypeCode_t for groups package is defined in GroupsExtension.h as follows:
typedef enum { SBML_GROUPS_GROUP = 200 , SBML_GROUPS_MEMBER = 201 } SBMLGroupsTypeCode_t;
SBML_GROUPS_GROUP corresponds to the Group class (<group>) and SBML_GROUPS_MEMBER corresponds to the Member (<member>) class, respectively.
Similarly, SBMLLayoutTypeCode_t for layout package is defined in LayoutExtension.h as follows:
typedef enum { SBML_LAYOUT_BOUNDINGBOX = 100 , SBML_LAYOUT_COMPARTMENTGLYPH = 101 , SBML_LAYOUT_CUBICBEZIER = 102 , SBML_LAYOUT_CURVE = 103 , SBML_LAYOUT_DIMENSIONS = 104 , SBML_LAYOUT_GRAPHICALOBJECT = 105 , SBML_LAYOUT_LAYOUT = 106 , SBML_LAYOUT_LINESEGMENT = 107 , SBML_LAYOUT_POINT = 108 , SBML_LAYOUT_REACTIONGLYPH = 109 , SBML_LAYOUT_SPECIESGLYPH = 110 , SBML_LAYOUT_SPECIESREFERENCEGLYPH = 111 , SBML_LAYOUT_TEXTGLYPH = 112 } SBMLLayoutTypeCode_t;
These enum values are returned by corresponding getTypeCode() functions. (e.g. SBML_GROUPS_GROUP is returned in Group::getTypeCode())
The value of each typecode can be duplicated between those of different packages (In the above SBMLayoutTypeCode_t and SBMLGroupsTypeCode_t types, unique values are assigned to enum values, but this is not mandatory.)
Thus, to distinguish the typecodes of different packages, not only the return value of getTypeCode() function but also that of getPackageName() function should be checked as follows:
void example (const SBase *sb) { const std::string pkgName = sb->getPackageName(); if (pkgName == "core") { switch (sb->getTypeCode()) { case SBML_MODEL: .... break; case SBML_REACTION: .... } } else if (pkgName == "layout") { switch (sb->getTypeCode()) { case SBML_LAYOUT_LAYOUT: .... break; case SBML_LAYOUT_REACTIONGLYPH: .... } } else if (pkgName == "groups") { switch (sb->getTypeCode()) { case SBML_GROUPS_GROUP: .... break; case SBML_GROUPS_MEMBER: .... } } ... }
Override the following pure virtual function which returns a string corresponding to the given typecode:
virtual const char* SBMLExtension::getStringFromTypeCode(int typeCode) const;
For example, the function for groups extension is implemented as follows:
static const char* SBML_GROUPS_TYPECODE_STRINGS[] = { "Group" , "Member" }; const char* GroupsExtension::getStringFromTypeCode(int typeCode) const { int min = SBML_GROUPS_GROUP; int max = SBML_GROUPS_MEMBER; if ( typeCode < min || typeCode > max) { return "(Unknown SBML Groups Type)"; } return SBML_GROUPS_TYPECODE_STRINGS[typeCode - min]; }
Implements a "static void init()" function in the derived class
In the init() function, initialization code which creates an instance of the derived class and registering code which registers the instance to SBMLExtensionRegistry class are implemented.
For example, the init() function for groups package is implemented as follows:
void GroupsExtension::init() { //------------------------------------------------------------------------- // // 1. Checks if the groups pacakge has already been registered. // //------------------------------------------------------------------------- if (SBMLExtensionRegistry::getInstance().isRegistered(getPackageName())) { // do nothing; return; } //------------------------------------------------------------------------- // // 2. Creates an SBMLExtension derived object. // //------------------------------------------------------------------------- GroupsExtension groupsExtension; //------------------------------------------------------------------------------------- // // 3. Creates SBasePluginCreatorBase derived objects required for this // extension. The derived classes can be instantiated by using the following // template class. // // temaplate<class SBasePluginType> class SBasePluginCreator // // The constructor of the creator class has two arguments: // // (1) SBaseExtensionPoint : extension point to which the plugin object connected // (2) std::vector<std::string> : a std::vector object that contains a list of URI // (package versions) supported by the plugin object. // // For example, two plugin objects (plugged in SBMLDocument and Model elements) are // required for the groups extension. // // Since only 'required' attribute is used in SBMLDocument by the groups package, and // the 'required' flag must always be 'false', the existing // SBMLDocumentPluginNotRequired class can be used as-is for the plugin. // // Since the lists of supported package versions (currently only L3V1-groups-V1 supported ) // are equal in the both plugin objects, the same vector object is given to each // constructor. // //--------------------------------------------------------------------------------------- std::vector<std::string> packageURIs; packageURIs.push_back(getXmlnsL3V1V1()); SBaseExtensionPoint sbmldocExtPoint("core",SBML_DOCUMENT); SBaseExtensionPoint modelExtPoint("core",SBML_MODEL); SBasePluginCreator<SBMLDocumentPluginNotRequired, GroupsExtension> sbmldocPluginCreator(sbmldocExtPoint,packageURIs); SBasePluginCreator<GroupsModelPlugin, GroupsExtension> modelPluginCreator(modelExtPoint,packageURIs); //-------------------------------------------------------------------------------------- // // 3. Adds the above SBasePluginCreatorBase derived objects to the SBMLExtension derived object. // //-------------------------------------------------------------------------------------- groupsExtension.addSBasePluginCreator(&sbmldocPluginCreator); groupsExtension.addSBasePluginCreator(&modelPluginCreator); //------------------------------------------------------------------------- // // 4. Registers the SBMLExtension derived object to SBMLExtensionRegistry // //------------------------------------------------------------------------- int result = SBMLExtensionRegistry::getInstance().addExtension(&groupsExtension); if (result != LIBSBML_OPERATION_SUCCESS) { std::cerr << "[Error] GroupsExtension::init() failed." << std::endl; } }
Instantiate a global SBMLExtensionRegister variable in appropriate implementation file
For example, the global variable for the groups extension is instantiated in GroupsExtension.cpp as follows:
static SBMLExtensionRegister<GroupsExtension> groupsExtensionRegister;
The init() function is invoked when the global variable is instantiated, by which initialization and registering the package extension are performed.