//-*-c++-*- /** Author: David Auber Email : auber@labri.fr Last modification : 20/08/2001 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. */ #include #include #include #include #include #if (__GNUC__ < 3) #include #else #include #endif #include #include #include #include #include #include #include "TLPParser.h" #define NODES "nodes" #define EDGE "edge" #define CLUSTER "cluster" #define CLUSTERNODES "nodes" #define CLUSTEREDGES "edges" #define PROPERTY "property" #define METRIC "metric" #define METAGRAPH "metagraph" #define LAYOUT "layout" #define SIZE "size" #define COLOR "color" #define COORD "coord" #define INT "int" #define UINT "uint" #define DOUBLE "double" #define FLOAT "float" #define STRING "string" #define BOOL "bool" #define NODESVALUE "node" #define EDGESVALUE "edge" #define DEFAULTVALUE "default" #define DISPLAYING "displaying" #define GLYPH "glyph" #define PLUGIN "plugin" using namespace std; //================================================================================= struct TLPGraphBuilder:public TLPTrue { SuperGraph *_superGraph; map nodeIndex; map edgeIndex; map clusterIndex; map subGraphIndex; DataSet *dataSet; bool cameraFlag; TLPGraphBuilder(SuperGraph *superGraph, DataSet *dataSet): _superGraph(superGraph), dataSet(dataSet), cameraFlag(false) { clusterIndex[0]=superGraph; } virtual ~TLPGraphBuilder(){ } bool addNode(int id) { nodeIndex[id]=_superGraph->addNode(); return true; } bool addClusterNode(int id,int nodeId) { clusterIndex[id]->addNode(nodeIndex[nodeId]); return true; } bool addClusterEdge(int id,int edgeId) { clusterIndex[id]->addEdge(edgeIndex[edgeId]); return true; } bool addEdge(int id,int idSource,int idTarget) { edgeIndex[id]=_superGraph->addEdge(nodeIndex[idSource],nodeIndex[idTarget]); return true; } bool setNodeValue(int nodeId, int clusterId, const string propertyType, const string propertyName, string value) { //cerr << "set node value ....." ; if (propertyType==METAGRAPH) { char *endPtr=0; const char *startPtr=value.c_str(); int result=strtol(startPtr,&endPtr,10); if (endPtr==startPtr) return false; if (clusterIndex.find(result)==clusterIndex.end()) return false; if (result==0) getLocalProxy(clusterIndex[clusterId],propertyName)->setNodeValue(nodeIndex[nodeId],0); else getLocalProxy(clusterIndex[clusterId],propertyName)->setNodeValue(nodeIndex[nodeId],clusterIndex[result]); return true; } if (propertyType==METRIC) return stringToNodeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), nodeIndex[nodeId], value); if (propertyType==LAYOUT) return stringToNodeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), nodeIndex[nodeId], value); if (propertyType==SIZE) return stringToNodeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), nodeIndex[nodeId], value); if (propertyType==COLOR) return stringToNodeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), nodeIndex[nodeId], value); if (propertyType==INT) return stringToNodeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), nodeIndex[nodeId], value); if (propertyType==BOOL) return stringToNodeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), nodeIndex[nodeId], value); if (propertyType==STRING) return stringToNodeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), nodeIndex[nodeId], value); return false; //cer << "..ok" << endl; } bool setEdgeValue(int edgeId, int clusterId, const string &propertyType, const string &propertyName, string value) { //cerr << "setEdgeValue...." << "edge:" << edgeId << " cluster " << clusterId << " " << propertyName << " " << propertyType << " value=\""<< value<<"\" "; bool result=false; if (propertyType==METAGRAPH) { char *endPtr=0; const char *startPtr=value.c_str(); int result=strtol(startPtr,&endPtr,10); if (endPtr==startPtr) return false; if (clusterIndex.find(result)==clusterIndex.end()) return false; if (result==0) getLocalProxy(clusterIndex[clusterId],propertyName)->setEdgeValue(edgeIndex[edgeId],0); else getLocalProxy(clusterIndex[clusterId],propertyName)->setEdgeValue(edgeIndex[edgeId],clusterIndex[result]); return true; } if (propertyType==METRIC) result= stringToEdgeProperty( getLocalProxy(clusterIndex[clusterId],propertyName), edgeIndex[edgeId], value); if (propertyType==LAYOUT) result= stringToEdgeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), edgeIndex[edgeId], value); if (propertyType==SIZE) result= stringToEdgeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), edgeIndex[edgeId], value); if (propertyType==COLOR) result= stringToEdgeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), edgeIndex[edgeId], value); if (propertyType==INT) result= stringToEdgeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), edgeIndex[edgeId], value); if (propertyType==BOOL) result= stringToEdgeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), edgeIndex[edgeId], value); if (propertyType==STRING) result= stringToEdgeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), edgeIndex[edgeId], value); //cer<< "..ok result=" << result<< endl; return result; } bool setAllNodeValue(int clusterId, const string propertyType, const string propertyName, string value) { //cerr << "set all node value ....." ; if (propertyType==METAGRAPH) { char *endPtr=0; const char *startPtr=value.c_str(); int result=strtol(startPtr,&endPtr,10); if (endPtr==startPtr) return false; if (clusterIndex.find(result)==clusterIndex.end()) return false; if (result==0) getLocalProxy(clusterIndex[clusterId],propertyName)->setAllNodeValue(0); else getLocalProxy(clusterIndex[clusterId],propertyName)->setAllNodeValue(clusterIndex[result]); return true; } if (propertyType==METRIC) return stringToAllNodeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), value); if (propertyType==LAYOUT) return stringToAllNodeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), value); if (propertyType==SIZE) return stringToAllNodeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), value); if (propertyType==COLOR) return stringToAllNodeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), value); if (propertyType==INT) return stringToAllNodeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), value); if (propertyType==BOOL) return stringToAllNodeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), value); if (propertyType==STRING) return stringToAllNodeProperty(getLocalProxy(clusterIndex[clusterId],propertyName), value); return false; //cer << "..ok" << endl; } bool setAllEdgeValue(int clusterId, const string &propertyType, const string &propertyName, string value) { //cerr << "setAllEdgeValue.." << endl; bool result=false; if (propertyType==METAGRAPH) { char *endPtr=0; const char *startPtr=value.c_str(); int result=strtol(startPtr,&endPtr,10); if (endPtr==startPtr) return false; if (clusterIndex.find(result)==clusterIndex.end()) return false; if (result==0) getLocalProxy(clusterIndex[clusterId],propertyName)->setAllEdgeValue(0); else getLocalProxy(clusterIndex[clusterId],propertyName)->setAllEdgeValue(clusterIndex[result]); return true; } if (propertyType==METRIC) result= stringToAllEdgeProperty( getLocalProxy(clusterIndex[clusterId], propertyName) , value); if (propertyType==LAYOUT) result= stringToAllEdgeProperty(getLocalProxy(clusterIndex[clusterId], propertyName) , value); if (propertyType==SIZE) result= stringToAllEdgeProperty( getLocalProxy(clusterIndex[clusterId], propertyName) , value); if (propertyType==COLOR) result= stringToAllEdgeProperty(getLocalProxy(clusterIndex[clusterId], propertyName) , value); if (propertyType==INT) result= stringToAllEdgeProperty(getLocalProxy(clusterIndex[clusterId], propertyName) , value); if (propertyType==BOOL) result= stringToAllEdgeProperty(getLocalProxy(clusterIndex[clusterId], propertyName) , value); if (propertyType==STRING) result= stringToAllEdgeProperty(getLocalProxy(clusterIndex[clusterId], propertyName) , value); //cer<< "..ok result=" << result<< endl; return result; } bool addCluster(int id, const string&name, int fatherId=0) { // //cer << "TLPGraphBuilder::Add Cluster " << name << endl; SelectionProxy *selProxy=getLocalProxy(clusterIndex[fatherId],"tmpSelection"); selProxy->setAllNodeValue(false); selProxy->setAllEdgeValue(false); subGraphIndex[id]=clusterIndex[fatherId]->addView(name,selProxy); clusterIndex[id]=subGraphIndex[id]->getAssociatedSuperGraph(); clusterIndex[fatherId]->getPropertyProxyContainer()->delLocalProxy("tmpSelection"); return true; } bool addStruct(const string& structName,TLPBuilder*&newBuilder) ; }; //================================================================================= struct TLPNodeBuilder:public TLPFalse { TLPGraphBuilder *graphBuilder; TLPNodeBuilder(TLPGraphBuilder *graphBuilder):graphBuilder(graphBuilder){} bool addInt(const int id) {return graphBuilder->addNode(id);} bool close(){return true;} }; //================================================================================= struct TLPEdgeBuilder:public TLPFalse { TLPGraphBuilder *graphBuilder; int parameter[3]; int nbParameter; TLPEdgeBuilder(TLPGraphBuilder *graphBuilder):graphBuilder(graphBuilder),nbParameter(0){} bool addInt(const int id) { if (nbParameter<3) { parameter[nbParameter]=id; nbParameter++; return true; } else return false; } bool close() { if (nbParameter==3) { return graphBuilder->addEdge(parameter[0],parameter[1],parameter[2]); } else return false; } }; //================================================================================= struct TLPClusterBuilder:public TLPFalse { TLPGraphBuilder *graphBuilder; int clusterId,fatherId; // string clusterName; TLPClusterBuilder(TLPGraphBuilder *graphBuilder,int father=0):graphBuilder(graphBuilder),fatherId(father){} bool addInt(const int id) { //cer << "TLPClusterBuilder::cluster id " << id << endl; clusterId=id; return true; } bool addString(const string &str) { //cer << "TLPClusterBuilder::cluster name " << str << endl; // clusterName=str; return graphBuilder->addCluster(clusterId , str, fatherId); } bool addStruct(const string& structName,TLPBuilder*&newBuilder); bool addNode (int nodeId) { return graphBuilder->addClusterNode(clusterId,nodeId); } bool addEdge (int edgeId) { return graphBuilder->addClusterEdge(clusterId,edgeId); } bool close(){return true;} }; //================================================================================= struct TLPClusterNodeBuilder:public TLPFalse { TLPClusterBuilder *clusterBuilder; TLPClusterNodeBuilder(TLPClusterBuilder *clusterBuilder):clusterBuilder(clusterBuilder){} bool addInt(const int id) {return clusterBuilder->addNode(id);} bool close(){return true;} }; //================================================================================= struct TLPClusterEdgeBuilder:public TLPFalse { TLPClusterBuilder *clusterBuilder; TLPClusterEdgeBuilder(TLPClusterBuilder *clusterBuilder):clusterBuilder(clusterBuilder){} bool addInt(const int id) {return clusterBuilder->addEdge(id);} bool close(){return true;} }; //================================================================================ struct TLPDisplayingBuilder: public TLPFalse { TLPGraphBuilder *graphBuilder; DataSet dataSet; TLPDisplayingBuilder(TLPGraphBuilder *graphBuilder):graphBuilder(graphBuilder){ graphBuilder->dataSet->get(DISPLAYING, dataSet); } virtual ~TLPDisplayingBuilder(){} bool addStruct(const string& structName, TLPBuilder*&newBuilder); bool close(){ graphBuilder->dataSet->set(DISPLAYING, dataSet); return true; } }; //================================================================================ struct TLPGlyphBuilder: public TLPFalse { TLPDisplayingBuilder *displayingBuilder; STL_EXT_NS::hash_map > glyphTable; int glyphIndex; TLPGlyphBuilder(TLPDisplayingBuilder *displayingBuilder) : displayingBuilder(displayingBuilder) { displayingBuilder->dataSet.get > >("glyphTable", glyphTable); } virtual ~TLPGlyphBuilder(){} bool addInt(const int id) {glyphIndex=id; return true;} bool addStruct(const string& structName, TLPBuilder*&newBuilder); bool close(){ displayingBuilder->dataSet.set("glyphTable", glyphTable); return true; } bool setPlugin(const string &val) { if (glyphIndex >= 0) { glyphTable[glyphIndex] = val; } #ifndef NDEBUG else { cerr << "TLPGlyphBuilder::setPlugin(" << val << "): glyphIndex=" << glyphIndex << ", Ignored insertion" << endl; } #endif return true; } }; //================================================================================ struct TLPPluginBuilder: public TLPFalse { TLPGlyphBuilder *glyphBuilder; TLPPluginBuilder(TLPGlyphBuilder *glyphBuilder) : glyphBuilder(glyphBuilder){} virtual ~TLPPluginBuilder(){} bool addString(const string&val) {return glyphBuilder->setPlugin(val);} bool close(){return true;} }; //================================================================================= struct TLPDisplayingPropertyBuilder : public TLPFalse { TLPDisplayingBuilder *displayingBuilder; DataSet *data; string type, prop; int token; TLPDisplayingPropertyBuilder(TLPDisplayingBuilder *displayingBuilder, const string& type): displayingBuilder(displayingBuilder), data(&(displayingBuilder->dataSet)), type(type), prop(""), token(0) {} ~TLPDisplayingPropertyBuilder(){} bool addString(const string &val) { switch(token++) { case 0: prop = val; break; case 1: { if (type==COLOR) { Color c; if (stringToColor(const_cast(val), c)) data->set(prop, c); else cerr << __PRETTY_FUNCTION__ << ": COLOR failed" << endl; //else return false; } else if (type==COORD) { Coord c; if (stringToCoord(const_cast(val), c)) data->set(prop, c); else cerr << __PRETTY_FUNCTION__ << ": COORD failed" << endl; //else return false; } else { cerr << __PRETTY_FUNCTION__ << ": TYPE = " << type << ", " << prop << " = " << val << endl; return false; } break; } default: return false; } return true; } bool addBool(const bool val) { if ((type==BOOL) && (token++ == 1)) data->set(prop, val); return true; } bool addInt(const int val) { if ((type==INT) && (token == 1)) { if (prop == "SupergraphId") { int v; if (displayingBuilder->graphBuilder->clusterIndex[val] != NULL) { v=displayingBuilder->graphBuilder->clusterIndex[val]->getId(); data->set(prop, v); } else cerr << "Import TLP: Warning: no cluster #" << val << " defined." << endl; } else { data->set(prop, val); } } else if ((type==UINT) && (token == 1)) { data->set(prop, val); } token++; return true; } bool addDouble(const double val) { if ((type==DOUBLE) && (token == 1)) { data->set(prop, val); token++; return true; } else if ((type==FLOAT) && (token == 1)) { data->set(prop, (float) val); token++; return true; } else return false; } bool close() {return (token==2);} }; //================================================================================= bool TLPClusterBuilder::addStruct(const string& structName,TLPBuilder*&newBuilder) { if (structName==CLUSTERNODES) { //cer << "TLPClusterBuilder::new nodes" << structName << endl; newBuilder=new TLPClusterNodeBuilder(this); } else if (structName==CLUSTEREDGES) { //cer << "TLPClusterBuilder::new edgess" << structName << endl; newBuilder=new TLPClusterEdgeBuilder(this); } else if (structName==CLUSTER) { //cer << "TLPClusterBuilder::new cluster" << structName << endl; newBuilder=new TLPClusterBuilder(graphBuilder,clusterId); } else { newBuilder=new TLPFalse(); return false; } return true; } //================================================================================= struct TLPPropertyBuilder:public TLPFalse { TLPGraphBuilder *graphBuilder; int clusterId; string propertyType,propertyName; bool typeOk,nameOk; virtual ~TLPPropertyBuilder() {} TLPPropertyBuilder(TLPGraphBuilder *graphBuilder):graphBuilder(graphBuilder),typeOk(false),nameOk(false){} bool addInt(const int id) { clusterId=id; return true; } bool addString(const string &str) { if (!typeOk) {propertyType=str;typeOk=true;} else if (!nameOk) {propertyName=str;nameOk=true;} else return false; return true; } bool setNodeValue(int nodeId, const string value) { return graphBuilder->setNodeValue(nodeId,clusterId,propertyType,propertyName,value); } bool setEdgeValue(int edgeId, const string value) { return graphBuilder->setEdgeValue(edgeId,clusterId,propertyType,propertyName,value); } bool setAllNodeValue(const string value) { return graphBuilder->setAllNodeValue(clusterId,propertyType,propertyName,value); } bool setAllEdgeValue(const string value) { return graphBuilder->setAllEdgeValue(clusterId,propertyType,propertyName,value); } bool addStruct(const string& structName,TLPBuilder*&newBuilder); bool close(){return true;} }; //================================================================================= struct TLPNodePropertyBuilder:public TLPFalse { TLPPropertyBuilder *propertyBuilder; int nodeId; TLPNodePropertyBuilder(TLPPropertyBuilder *propertyBuilder):propertyBuilder(propertyBuilder){} bool addInt(const int id) {nodeId=id;return true;} bool addString(const string&val) {return propertyBuilder->setNodeValue(nodeId,val);} bool close(){return true;} }; //================================================================================= struct TLPEdgePropertyBuilder:public TLPFalse { TLPPropertyBuilder *propertyBuilder; int edgeId; string nodeValue; TLPEdgePropertyBuilder(TLPPropertyBuilder *propertyBuilder):propertyBuilder(propertyBuilder){} virtual ~TLPEdgePropertyBuilder(){} bool addInt(const int id) {edgeId=id;return true;} bool addString(const string &val) {return propertyBuilder->setEdgeValue(edgeId,val);} bool close(){return true;} }; struct TLPDefaultPropertyBuilder:public TLPFalse { TLPPropertyBuilder *propertyBuilder; int edgeId; string nodeValue; int i; TLPDefaultPropertyBuilder(TLPPropertyBuilder *propertyBuilder):propertyBuilder(propertyBuilder),i(0){} virtual ~TLPDefaultPropertyBuilder(){} bool addString(const string &val) { if (i==0) {i++;return propertyBuilder->setAllNodeValue(val);} if (i==1) {i++;return propertyBuilder->setAllEdgeValue(val);} return false; } bool close(){return true;} }; //================================================================================= bool TLPPropertyBuilder::addStruct(const string& structName,TLPBuilder*&newBuilder) { if (structName==DEFAULTVALUE) { newBuilder= new TLPDefaultPropertyBuilder(this); return true; } else if (structName==NODESVALUE) { newBuilder=new TLPNodePropertyBuilder(this); return true; } else if (structName==EDGESVALUE) { newBuilder=new TLPEdgePropertyBuilder(this); return true; } return false; } //================================================================================= bool TLPGraphBuilder::addStruct(const string& structName,TLPBuilder*&newBuilder) { if (structName==NODES) { newBuilder=new TLPNodeBuilder(this); } else if (structName==EDGE) { newBuilder=new TLPEdgeBuilder(this); } else if (structName==CLUSTER) { newBuilder=new TLPClusterBuilder(this); } else if (structName==PROPERTY) { newBuilder=new TLPPropertyBuilder(this); } else if (structName==DISPLAYING) { newBuilder=new TLPDisplayingBuilder(this); } else newBuilder=new TLPTrue(); return true; } //================================================================================ bool TLPDisplayingBuilder::addStruct(const string& structName,TLPBuilder*&newBuilder) { if (structName==GLYPH) { newBuilder=new TLPGlyphBuilder(this); } else if (structName==COORD || structName==COLOR || structName==BOOL || structName==INT || structName==UINT || structName==FLOAT || structName==DOUBLE) { newBuilder=new TLPDisplayingPropertyBuilder(this, structName); } else newBuilder= new TLPTrue(); return true; } //================================================================================ bool TLPGlyphBuilder::addStruct(const string& structName,TLPBuilder*&newBuilder) { if (structName==PLUGIN) { newBuilder=new TLPPluginBuilder(this); } else newBuilder=new TLPTrue(); return true; } //================================================================================ //================================================================================ struct TLPImport:public ImportModule { public: TLPImport(ClusterContext context):ImportModule(context) { addParameter("filename"); addParameter(DISPLAYING); } ~TLPImport(){} bool import(const string &dummy) { string filename; dataSet->get("filename", filename); struct stat infoEntry; lstat(filename.c_str(),&infoEntry); int size=infoEntry.st_size; //cer << "Opening file" << endl; istream *input; if (filename.rfind(".gz") == (filename.length() - 3)) input = new igzstream(filename.c_str()); else input = new ifstream(filename.c_str()); TLPParser myParser(*input, new TLPGraphBuilder(superGraph, dataSet),pluginProgress,size); //TLPParser myParser(myFile,new TLPWriter()); bool result = myParser.parse(); delete input; cerr << "Import Finished" << flush << endl; return result; // return true; } }; IMPORTPLUGIN(TLPImport,"tlp","Auber","16/02/2001","0","0","1");