static void readSequenceAnnotationReferences(xmlNode *node) { SequenceAnnotation *ann; xmlChar *path; xmlChar *ann_uri; xmlChar *ref_uri; xmlNode *ref_node; PointerArray *results; int n; // get SequenceAnnotation ann_uri = getNodeURI(node); ann = getSequenceAnnotation(DESTINATION, (char *)ann_uri); xmlFree(ann_uri); // add subComponent path = BAD_CAST "./" NSPREFIX_SBOL ":" NODENAME_SUBCOMPONENT "/" NSPREFIX_SBOL ":" NODENAME_DNACOMPONENT; if ((ref_uri = getURIOfNodeMatchingXPath(node, path))) { setSequenceAnnotationSubComponent(ann, getDNAComponent(DESTINATION, (char *)ref_uri)); xmlFree(ref_uri); } // add precedes path = BAD_CAST "./" NSPREFIX_SBOL ":" NODENAME_PRECEDES; if ((results = getNodesMatchingXPath(node, path))) { for (n=0; n<getNumPointersInArray(results); n++) { ref_node = (xmlNode *) getNthPointerInArray(results, n); ref_uri = getNodeURI(ref_node); addPrecedesRelationship(ann, getSequenceAnnotation(DESTINATION, (char *)ref_uri)); xmlFree(ref_uri); } deletePointerArray(results); } }
static void readCollectionReferences(xmlNode *node) { Collection *col; xmlChar *path; xmlChar *col_uri; xmlChar *ref_uri; PointerArray *ref_nodes; xmlNode *ref_node; int n; // get Collection col_uri = getNodeURI(node); col = getCollection(DESTINATION, (char *)col_uri); xmlFree(col_uri); // add components path = BAD_CAST "./" NSPREFIX_SBOL ":" NODENAME_COMPONENT "/" NSPREFIX_SBOL ":" NODENAME_DNACOMPONENT; if ((ref_nodes = getNodesMatchingXPath(node, path))) { for (n=0; n<getNumPointersInArray(ref_nodes); n++) { ref_node = (xmlNode *) getNthPointerInArray(ref_nodes, n); ref_uri = getNodeURI(ref_node); addDNAComponentToCollection(col, getDNAComponent(DESTINATION, (char *)ref_uri)); xmlFree(ref_uri); } deletePointerArray(ref_nodes); } }
// Returns a structured annotation as a libXML2 xml node xmlNode* getNthStructuredAnnotationAsXML(SBOLObject* obj, const int n) { if (n >= getNumStructuredAnnotations(obj)) { return NULL; } else { return (xmlNode *)getNthPointerInArray(obj->xml_annotations, n); } }
SequenceAnnotation* getNthPrecedes(const SequenceAnnotation* ann, int n) { if (ann && getNumPrecedes(ann) >= n) { char *uri = (char *)getNthPointerInArray(ann->precedes, n); return getSequenceAnnotation(ann->doc, uri); } else return NULL; }
static void applyFunctionToNodesMatchingXPath(void (*fn)(xmlNode *), xmlNode *node, xmlChar *path) { if (!path) return; PointerArray *results = getNodesMatchingXPath(node, path); if (results) { if (getNumPointersInArray(results) > 0) { int n; for (n=0; n<getNumPointersInArray(results); n++) fn(getNthPointerInArray(results, n)); } deletePointerArray(results); } }
static xmlNode *getSingleNodeMatchingXPath(xmlNode *node, xmlChar *path) { PointerArray *results_array = getNodesMatchingXPath(node, path); if (!results_array) return NULL; else if (getNumPointersInArray(results_array) == 0) { deletePointerArray(results_array); return NULL; } else { if (getNumPointersInArray(results_array) > 1) { #ifdef SBOL_DEBUG_STATEMENTS printf("Got too many nodes matching xpath %s\n", (char *)path); #endif } xmlNode *result = getNthPointerInArray(results_array, 0); deletePointerArray(results_array); return result; } }
static void readDNAComponentContent(xmlNode *node) { DNAComponent *com; xmlChar *com_uri; xmlChar *path; xmlChar *type_property; xmlNode *type_node; xmlNode *child_node; // structured xml annotation PointerArray *results; int i; // create DNAComponent com_uri = getNodeURI(node); com = createDNAComponent(DESTINATION, (char *)com_uri); xmlFree(com_uri); // add displayID, name, description readSBOLCompoundObject(com->base, node); // add type path = (unsigned char*)NSPREFIX_RDF ":" NODENAME_TYPE; if ((results = getNodesMatchingXPath(node, path))) { type_node = (xmlNode *)getNthPointerInArray(results, 0); type_property = xmlGetNsProp(type_node, BAD_CAST NODENAME_RESOURCE, BAD_CAST NSURL_RDF); setDNAComponentType(com, (char *)type_property); xmlFree(results); } // scan other xml nodes attached to this DNAComponent for structured xml annotations // @TODO factor out this block of code. This routine is generally used by each of the SBOL core objects // but it requires some custom knowledge of the calling object (in this case, DNAComponent) child_node = node->children; while (child_node) { if (child_node->ns && !isSBOLNamespace(child_node->ns->href)) { // copy xml tree and save it in the SBOLDocument object as a structural annotation xmlNode* node_copy = xmlDocCopyNode(child_node, com->doc->xml_doc, 1); node_copy = xmlAddChild(xmlDocGetRootElement(com->doc->xml_doc), node_copy); i = xmlReconciliateNs(com->doc->xml_doc, xmlDocGetRootElement(com->doc->xml_doc)); insertPointerIntoArray(com->base->base->xml_annotations, node_copy); } child_node = child_node->next; } }
void removePrecedesRelationship(SequenceAnnotation* upstream, SequenceAnnotation* downstream) { if (upstream && downstream) { char *target_uri = getSequenceAnnotationURI(downstream); char *query_uri; int FOUND = 0; // found URI in list of URIs int EOL = 0; // end of list int i_uri = 0; // index of URI in list while (!FOUND && !EOL) { query_uri = (char *)getNthPointerInArray(upstream->precedes, i_uri); if (strcmp(query_uri, target_uri) == 0) { FOUND++; removePointerFromArray(upstream->precedes, i_uri); } i_uri++; if (i_uri == getNumPointersInArray(upstream->precedes)) { EOL++; } } } return; }
SequenceAnnotation* copySequenceAnnotation(SequenceAnnotation* ann, char* id_modifier) { int i; char* copy_uri = augmentURI(getSequenceAnnotationURI(ann), id_modifier); SequenceAnnotation* copy = createSequenceAnnotation(ann->doc, copy_uri); setSequenceAnnotationStart(copy, getSequenceAnnotationStart(ann)); setSequenceAnnotationEnd(copy, getSequenceAnnotationEnd(ann)); setSequenceAnnotationStrand(copy, getSequenceAnnotationStrand(ann)); // Copy precedes property copy->precedes = createPointerArray(); char *target_uri; for (i = 0; i < getNumPointersInArray(ann->precedes); i++) { target_uri = (char *)getNthPointerInArray(ann->precedes, i); insertPointerIntoArray(copy->precedes, augmentURI(target_uri, id_modifier)); } // Copy SubComponent tree recursively if (ann->subComponent) { char* sub_com_uri = augmentURI(getDNAComponentURI(ann->subComponent), id_modifier); DNAComponent* sub_com_copy = createDNAComponent(ann->doc, sub_com_uri); setSequenceAnnotationSubComponent(copy, sub_com_copy); } return (SequenceAnnotation *)copy; }
static void readDNAComponentReferences(xmlNode *node) { DNAComponent *com; xmlChar *path; xmlChar *com_uri; xmlChar *ref_uri; PointerArray *ref_nodes; xmlNode *ref_node; int n; // get DNAComponent com_uri = getNodeURI(node); com = getDNAComponent(DESTINATION, (char *)com_uri); xmlFree(com_uri); // add sequence path = BAD_CAST "./" NSPREFIX_SBOL ":" NODENAME_DNASEQUENCE_REF "/" NSPREFIX_SBOL ":" NODENAME_DNASEQUENCE; if ((ref_uri = getURIOfNodeMatchingXPath(node, path))) { setDNAComponentSequence(com, getDNASequence(DESTINATION, (char *)ref_uri)); xmlFree(ref_uri); } // add annotations path = BAD_CAST "./" NSPREFIX_SBOL ":" NODENAME_ANNOTATION "/" NSPREFIX_SBOL ":" NODENAME_SEQUENCEANNOTATION; if ((ref_nodes = getNodesMatchingXPath(node, path))) { for (n=0; n<getNumPointersInArray(ref_nodes); n++) { ref_node = (xmlNode *) getNthPointerInArray(ref_nodes, n); ref_uri = getNodeURI(ref_node); addSequenceAnnotation(com, getSequenceAnnotation(DESTINATION, (char *)ref_uri)); xmlFree(ref_uri); } deletePointerArray(ref_nodes); } }
DNAComponent* getNthDNAComponentIn(const Collection* col, int n) { if (col) return (DNAComponent *)getNthPointerInArray(col->components, n); else return NULL; }
SequenceAnnotation* getNthPrecedes(const SequenceAnnotation* ann, int n) { if (ann && getNumPrecedes(ann) >= n) return (SequenceAnnotation*) getNthPointerInArray(ann->precedes, n); else return NULL; }