//read all cluster tree information bool GmlParser::clusterRead(GmlObject* rootCluster, ClusterGraph& CG) { //the root cluster is only allowed to hold child clusters and //nodes in a list if (rootCluster->m_valueType != gmlListBegin) return false; // read all clusters and nodes GmlObject *rootClusterSon = rootCluster->m_pFirstSon; for(; rootClusterSon; rootClusterSon = rootClusterSon->m_pBrother) { switch(id(rootClusterSon)) { case clusterPredefKey: { //we could delete this, but we aviod the call if (rootClusterSon->m_valueType != gmlListBegin) return false; // set attributes to default values //we currently do not set any values cluster c = CG.newCluster(CG.rootCluster()); //recursively read cluster recursiveClusterRead(rootClusterSon, CG, c); } //case cluster break; case vertexPredefKey: //direct root vertices { if (rootClusterSon->m_valueType != gmlStringValue) return false; String vIDString = rootClusterSon->m_stringValue; //we only allow a vertex id as string identification if ((vIDString[0] != 'v') && (!isdigit(vIDString[0])))return false; //do not allow labels //if old style entry "v"i if (!isdigit(vIDString[0])) //should check prefix? vIDString[0] = '0'; //leading zero to allow conversion int vID = atoi(vIDString.cstr()); OGDF_ASSERT(m_mapToNode[vID] != 0) //we assume that no node is already assigned ! Changed: //all new nodes are assigned to root //CG.reassignNode(mapToNode[vID], CG.rootCluster()); //it seems that this may be unnessecary, TODO check CG.reassignNode(m_mapToNode[vID], CG.rootCluster()); //char* vIDChar = new char[vIDString.length()+1]; //for (int ind = 1; ind < vIDString.length(); ind++) // vIDChar }//case vertex }//switch }//for all rootcluster sons return true; }//clusterread
//recursively read cluster subtree information bool GmlParser::recursiveClusterRead(GmlObject* clusterObject, ClusterGraph& CG, cluster c) { //for direct root cluster sons, this is checked twice... if (clusterObject->m_valueType != gmlListBegin) return false; GmlObject *clusterSon = clusterObject->m_pFirstSon; for(; clusterSon; clusterSon = clusterSon->m_pBrother) { //we dont read the attributes, therefore look only for //id and sons switch(id(clusterSon)) { case clusterPredefKey: { if (clusterSon->m_valueType != gmlListBegin) return false; cluster cson = CG.newCluster(c); //recursively read child cluster recursiveClusterRead(clusterSon, CG, cson); } break; case vertexPredefKey: //direct cluster vertex entries { if (clusterSon->m_valueType != gmlStringValue) return false; string vIDString = clusterSon->m_stringValue; //if old style entry "v"i if ((vIDString[0] != 'v') && (!isdigit((int)vIDString[0])))return false; //do not allow labels //if old style entry "v"i if (!isdigit((int)vIDString[0])) //should check prefix? vIDString[0] = '0'; //leading zero to allow conversion int vID = stoi(vIDString); OGDF_ASSERT(m_mapToNode[vID] != 0) //we assume that no node is already assigned //CG.reassignNode(mapToNode[vID], c); //changed: all nodes are already assigned to root CG.reassignNode(m_mapToNode[vID], c); //char* vIDChar = new char[vIDString.length()+1]; //for (int ind = 1; ind < vIDString.length(); ind++) // vIDChar }//case vertex }//switch }//for clustersons return true; }//recursiveclusterread
bool GraphMLParser::readClusters( Graph &G, ClusterGraph &C, ClusterGraphAttributes *CA, const cluster &rootCluster, const pugi::xml_node rootTag) { for(pugi::xml_node nodeTag : rootTag.children("node")) { pugi::xml_attribute idAttr = nodeTag.attribute("id"); pugi::xml_node clusterTag = nodeTag.child("graph"); if (clusterTag == nullptr) { // Got normal node then, add it to the graph - id is required. if (!idAttr) { GraphIO::logger.lout() << "Node is missing id attribute." << endl; return false; } const node v = G.newNode(); m_nodeId[idAttr.value()] = v; C.reassignNode(v, rootCluster); // Read attributes when CA given and return false if error. if(CA && !readAttributes(*CA, v, nodeTag)) { return false; } } else { // Got a cluster node - read it recursively. const cluster c = C.newCluster(rootCluster); if (!readClusters(G, C, CA, c, clusterTag)) { return false; } // Read attributes when CA given and return false if error. if(CA && !readAttributes(*CA, c, nodeTag)) { return false; } } } return readEdges(G, CA, rootTag); }
bool Parser::readCluster( Graph &G, ClusterGraph &C, ClusterGraphAttributes *CA, cluster rootCluster, const XmlTagObject &rootTag) { List<XmlTagObject *> nodeTags; rootTag.findSonXmlTagObjectByName("node", nodeTags); for(XmlTagObject *obj : nodeTags) { const XmlTagObject &nodeTag = *obj; XmlAttributeObject *idAttr; nodeTag.findXmlAttributeObjectByName("id", idAttr); if(!idAttr) { OGDF_ERROR("node is missing an attribute " << "(line " << nodeTag.getLine() << ")."); } // Node is a cluster iff it contains other nodes. XmlTagObject *nodesTag; nodeTag.findSonXmlTagObjectByName("nodes", nodesTag); if(nodesTag) { // Node tag found, therefore it is a cluster. const cluster c = C.newCluster(rootCluster); m_clusterId[idAttr->getValue()] = c; if(!readCluster(G, C, CA, c, *nodesTag)) { return false; } } else { // Node tag not found, therefore it is "normal" node. const node v = G.newNode(); C.reassignNode(v, rootCluster); m_nodeId[idAttr->getValue()] = v; if(CA) { readAttributes(*CA, v, nodeTag); } } } return true; }
//recursively read cluster subtree information bool GmlParser::recursiveAttributedClusterRead(GmlObject* clusterObject, ClusterGraph& CG, ClusterGraphAttributes& ACG, cluster c) { //for direct root cluster sons, this is checked twice... if (clusterObject->m_valueType != gmlListBegin) return false; GmlObject *clusterSon = clusterObject->m_pFirstSon; for(; clusterSon; clusterSon = clusterSon->m_pBrother) { //we dont read the attributes, therefore look only for //id and sons switch(id(clusterSon)) { case clusterPredefKey: { if (clusterSon->m_valueType != gmlListBegin) return false; cluster cson = CG.newCluster(c); //recursively read child cluster recursiveAttributedClusterRead(clusterSon, CG, ACG, cson); } break; case labelPredefKey: { if (clusterSon->m_valueType != gmlStringValue) return false; ACG.clusterLabel(c) = clusterSon->m_stringValue; } break; case templatePredefKey: { if (clusterSon->m_valueType != gmlStringValue) return false; ACG.templateCluster(c) = clusterSon->m_stringValue; break; } case graphicsPredefKey: //read the info for cluster c { if (clusterSon->m_valueType != gmlListBegin) return false; readClusterAttributes(clusterSon, c , ACG); }//graphics break; case vertexPredefKey: //direct cluster vertex entries { if (clusterSon->m_valueType != gmlStringValue) return false; String vIDString = clusterSon->m_stringValue; if ((vIDString[0] != 'v') && (!isdigit(vIDString[0])))return false; //do not allow labels //if old style entry "v"i if (!isdigit(vIDString[0])) //should check prefix? vIDString[0] = '0'; //leading zero to allow conversion int vID = atoi(vIDString.cstr()); OGDF_ASSERT(m_mapToNode[vID] != 0) //we assume that no node is already assigned //changed: all nodes are already assigned to root CG.reassignNode(m_mapToNode[vID], c); }//case vertex }//switch }//for clustersons return true; }//recursiveAttributedClusterRead