diff options
Diffstat (limited to 'src/plantuml.cpp')
-rw-r--r-- | src/plantuml.cpp | 397 |
1 files changed, 342 insertions, 55 deletions
diff --git a/src/plantuml.cpp b/src/plantuml.cpp index ada035b..6966100 100644 --- a/src/plantuml.cpp +++ b/src/plantuml.cpp @@ -14,23 +14,32 @@ */ #include "plantuml.h" +#include "util.h" #include "portable.h" #include "config.h" #include "doxygen.h" #include "index.h" #include "message.h" +#include "debug.h" #include <qdir.h> +#include <qdict.h> +#include <qlist.h> -static const int maxCmdLine = 40960; -QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,const QCString &content) +QCString PlantumlManager::writePlantUMLSource(const QCString &outDir,const QCString &fileName,const QCString &content,OutputFormat format) { - QCString baseName(4096); + QCString baseName; + QCString puName; + QCString imgName; static int umlindex=1; + Debug::print(Debug::Plantuml,0,"*** %s fileName: %s\n","writePlantUMLSource",qPrint(fileName)); + Debug::print(Debug::Plantuml,0,"*** %s outDir: %s\n","writePlantUMLSource",qPrint(outDir)); + if (fileName.isEmpty()) // generate name { + puName = "inline_umlgraph_"+QCString().setNum(umlindex); baseName = outDir+"/inline_umlgraph_"+QCString().setNum(umlindex++); } else // user specified name @@ -38,29 +47,158 @@ QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,con baseName = fileName; int i=baseName.findRev('.'); if (i!=-1) baseName = baseName.left(i); + puName = baseName; baseName.prepend(outDir+"/"); } - QFile file(baseName+".pu"); - if (!file.open(IO_WriteOnly)) + + switch (format) { - err("Could not open file %s for writing\n",baseName.data()); + case PUML_BITMAP: + imgName =puName+".png"; + break; + case PUML_EPS: + imgName =puName+".eps"; + break; + case PUML_SVG: + imgName =puName+".svg"; + break; } - QCString text = "@startuml\n"; + + Debug::print(Debug::Plantuml,0,"*** %s baseName: %s\n","writePlantUMLSource",qPrint(baseName)); + Debug::print(Debug::Plantuml,0,"*** %s puName: %s\n","writePlantUMLSource",qPrint(puName)); + Debug::print(Debug::Plantuml,0,"*** %s imgName: %s\n","writePlantUMLSource",qPrint(imgName)); + + QCString text = "@startuml "+imgName+"\n"; text+=content; text+="\n@enduml\n"; - file.writeBlock( text, text.length() ); - file.close(); + + QCString qcOutDir(outDir); + uint pos = qcOutDir.findRev("/"); + QCString generateType(qcOutDir.right(qcOutDir.length() - (pos + 1)) ); + Debug::print(Debug::Plantuml,0,"*** %s generateType: %s\n","writePlantUMLSource",qPrint(generateType)); + PlantumlManager::instance()->insert(generateType,puName,format,text); + Debug::print(Debug::Plantuml,0,"*** %s generateType: %s\n","writePlantUMLSource",qPrint(generateType)); + return baseName; } -void generatePlantUMLOutput(const char *baseName,const char *outDir,PlantUMLOutputFormat format) +void PlantumlManager::generatePlantUMLOutput(const char *baseName,const char *outDir,OutputFormat format) +{ + QCString plantumlJarPath = Config_getString(PLANTUML_JAR_PATH); + QCString plantumlConfigFile = Config_getString(PLANTUML_CFG_FILE); + QCString dotPath = Config_getString(DOT_PATH); + + QCString imgName = baseName; + // The basename contains path, we need to strip the path from the filename in order + // to create the image file name which should be included in the index.qhp (Qt help index file). + int i; + if ((i=imgName.findRev('/'))!=-1) // strip path + { + imgName=imgName.right(imgName.length()-i-1); + } + switch (format) + { + case PUML_BITMAP: + imgName+=".png"; + break; + case PUML_EPS: + imgName+=".eps"; + break; + case PUML_SVG: + imgName+=".svg"; + break; + } + + Doxygen::indexList->addImageFile(imgName); +} + +//-------------------------------------------------------------------- + +PlantumlManager *PlantumlManager::m_theInstance = 0; + +PlantumlManager *PlantumlManager::instance() +{ + if (!m_theInstance) + { + m_theInstance = new PlantumlManager; + QCString outputFilename = Config_getString(OUTPUT_DIRECTORY) + "/" + CACHE_FILENAME; + QFileInfo fi(outputFilename); + if (fi.exists()) + { + m_theInstance->m_cachedPlantumlAllContent = fileToString(outputFilename); + } + else + { + m_theInstance->m_cachedPlantumlAllContent = ""; + } + Debug::print(Debug::Plantuml,0,"*** instance() : m_cachedPlantumlAllContent = [%s]\n",qPrint(m_theInstance->m_cachedPlantumlAllContent)); + m_theInstance->m_pngPlantumlContent.clear(); + m_theInstance->m_svgPlantumlContent.clear(); + m_theInstance->m_epsPlantumlContent.clear(); + } + return m_theInstance; +} + +PlantumlManager::PlantumlManager() { - static QCString plantumlJarPath = Config_getString(PLANTUML_JAR_PATH); - static QCString plantumlConfigFile = Config_getString(PLANTUML_CFG_FILE); - static QCString dotPath = Config_getString(DOT_PATH); +} + +PlantumlManager::~PlantumlManager() +{ + { + QDictIterator< QList<QCString> > it( m_pngPlantumlFiles); // See QDictIterator + QList<QCString> *list; + for (it.toFirst();(list=it.current());++it) + { + (*list).clear(); + } + m_pngPlantumlFiles.clear(); + m_pngPlantumlContent.clear(); + } + { + QDictIterator< QList<QCString> > it( m_epsPlantumlFiles); // See QDictIterator + QList<QCString> *list; + for (it.toFirst();(list=it.current());++it) + { + (*list).clear(); + } + m_epsPlantumlFiles.clear(); + m_epsPlantumlContent.clear(); + } + { + QDictIterator< QList<QCString> > it( m_svgPlantumlFiles); // See QDictIterator + QList<QCString> *list; + for (it.toFirst();(list=it.current());++it) + { + (*list).clear(); + } + m_svgPlantumlFiles.clear(); + m_svgPlantumlContent.clear(); + } +} + +static void runPlantumlContent(const QDict< QList <QCString> > &plantumlFiles, + const QDict< QCString > &plantumlContent, + PlantumlManager::OutputFormat format) +{ + /* example : running: java -Djava.awt.headless=true + -jar "/usr/local/bin/plantuml.jar" + -o "test_doxygen/DOXYGEN_OUTPUT/html" + -tpng + "test_doxygen/DOXYGEN_OUTPUT/html/A.pu" + -charset UTF-8 + outDir:test_doxygen/DOXYGEN_OUTPUT/html + test_doxygen/DOXYGEN_OUTPUT/html/A + */ + int exitCode; + QCString plantumlJarPath = Config_getString(PLANTUML_JAR_PATH); + QCString plantumlConfigFile = Config_getString(PLANTUML_CFG_FILE); + QCString dotPath = Config_getString(DOT_PATH); QCString pumlExe = "java"; QCString pumlArgs = ""; + QCString pumlType = ""; + QCString pumlOutDir = ""; QStrList &pumlIncludePathList = Config_getList(PLANTUML_INCLUDE_PATH); char *s=pumlIncludePathList.first(); @@ -92,61 +230,210 @@ void generatePlantUMLOutput(const char *baseName,const char *outDir,PlantUMLOutp pumlArgs += portable_commandExtension(); pumlArgs += "\" "; } - pumlArgs+="-o \""; - pumlArgs+=outDir; - pumlArgs+="\" "; - QCString imgName = baseName; - // The basename contains path, we need to strip the path from the filename in order - // to create the image file name which should be included in the index.qhp (Qt help index file). - int i; - if ((i=imgName.findRev('/'))!=-1) // strip path - { - imgName=imgName.right(imgName.length()-i-1); - } switch (format) { - case PUML_BITMAP: - pumlArgs+="-tpng"; - imgName+=".png"; + case PlantumlManager::PUML_BITMAP: + pumlType="png"; break; - case PUML_EPS: - pumlArgs+="-teps"; - imgName+=".eps"; + case PlantumlManager::PUML_EPS: + pumlType="eps"; break; - case PUML_SVG: - pumlArgs+="-tsvg"; - imgName+=".svg"; + case PlantumlManager::PUML_SVG: + pumlType="svg"; break; } - pumlArgs+=" \""; - pumlArgs+=baseName; - pumlArgs+=".pu\" "; - pumlArgs+="-charset UTF-8 "; - int exitCode; - //printf("*** running: %s %s outDir:%s %s\n",pumlExe.data(),pumlArgs.data(),outDir,baseName); - msg("Running PlantUML on generated file %s.pu\n",baseName); - portable_sysTimerStart(); - if ((exitCode=portable_system(pumlExe,pumlArgs,TRUE))!=0) + { - err("Problems running PlantUML. Verify that the command 'java -jar \"%splantuml.jar\" -h' works from the command line. Exit code: %d\n", - plantumlJarPath.data(),exitCode); + QDictIterator< QCString > it( plantumlContent); // See QDictIterator + QCString *nb; + for (it.toFirst();(nb=it.current());++it) + { + QCString pumlArguments(pumlArgs); + msg("Generating PlantUML %s Files in %s\n",qPrint(pumlType),qPrint(it.currentKey())); + pumlArguments+="-o \""; + pumlArguments+=Config_getString(OUTPUT_DIRECTORY); + pumlArguments+="/"; + pumlArguments+=it.currentKey(); + pumlArguments+="\" "; + pumlArguments+="-charset UTF-8 -t"; + pumlArguments+=pumlType; + pumlArguments+=" "; + + QCString puFileName(""); + puFileName+=Config_getString(OUTPUT_DIRECTORY); + puFileName+="/"; + puFileName+=it.currentKey(); + puFileName+="/"; + pumlOutDir=puFileName; + puFileName+="inline_umlgraph_"; + puFileName+=pumlType; + puFileName+=it.currentKey(); + puFileName+=".pu"; + + pumlArguments+="\""; + pumlArguments+=puFileName; + pumlArguments+="\" "; + + QFile file(puFileName); + if (!file.open(IO_WriteOnly)) + { + err("Could not open file %s for writing\n",puFileName.data()); + } + file.writeBlock( *nb, nb->length() ); + file.close(); + Debug::print(Debug::Plantuml,0,"*** %s Running Plantuml arguments:%s\n","PlantumlManager::runPlantumlContent",qPrint(pumlArguments)); + + portable_sysTimerStart(); + if ((exitCode=portable_system(pumlExe,pumlArguments,TRUE))!=0) + { + err("Problems running PlantUML. Verify that the command 'java -jar \"%splantuml.jar\" -h' works from the command line. Exit code: %d\n", + plantumlJarPath.data(),exitCode); + } + else if (Config_getBool(DOT_CLEANUP)) + { + Debug::print(Debug::Plantuml,0,"*** %s Remove %s file\n","PlantumlManager::runPlantumlContent",qPrint(puFileName)); + file.remove(); + } + portable_sysTimerStop(); + + if ( (format==PlantumlManager::PUML_EPS) && (Config_getBool(USE_PDFLATEX)) ) + { + Debug::print(Debug::Plantuml,0,"*** %s Running epstopdf\n","PlantumlManager::runPlantumlContent"); + QList<QCString> *list = plantumlFiles[it.currentKey()]; + if (list) + { + QListIterator<QCString> li(*list); + QCString *nb; + for (li.toFirst();(nb=li.current());++li) + { + const int maxCmdLine = 40960; + QCString epstopdfArgs(maxCmdLine); + epstopdfArgs.sprintf("\"%s%s.eps\" --outfile=\"%s%s.pdf\"",qPrint(pumlOutDir),qPrint(*nb),qPrint(pumlOutDir),qPrint(*nb)); + portable_sysTimerStart(); + if ((exitCode=portable_system("epstopdf",epstopdfArgs))!=0) + { + err("Problems running epstopdf. Check your TeX installation! Exit code: %d\n",exitCode); + } + portable_sysTimerStop(); + } + } + } + } } - else if (Config_getBool(DOT_CLEANUP)) +} + +void PlantumlManager::run() +{ + Debug::print(Debug::Plantuml,0,"*** %s\n","PlantumlManager::run"); + runPlantumlContent(m_pngPlantumlFiles, m_pngPlantumlContent, PUML_BITMAP); + runPlantumlContent(m_svgPlantumlFiles, m_svgPlantumlContent, PUML_SVG); + runPlantumlContent(m_epsPlantumlFiles, m_epsPlantumlContent, PUML_EPS); + QCString outputFilename = Config_getString(OUTPUT_DIRECTORY) + "/" + CACHE_FILENAME; + QFile file(outputFilename); + if (!file.open(IO_WriteOnly)) { - QFile(QCString(baseName)+".pu").remove(); + err("Could not open file %s for writing\n",CACHE_FILENAME); } - portable_sysTimerStop(); - if ( (format==PUML_EPS) && (Config_getBool(USE_PDFLATEX)) ) + file.writeBlock( m_currentPlantumlAllContent, m_currentPlantumlAllContent.length() ); + file.close(); +} + +static void print(const QDict< QList <QCString> > &plantumlFiles) +{ + if (Debug::isFlagSet(Debug::Plantuml)) { - QCString epstopdfArgs(maxCmdLine); - epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"",baseName,baseName); - portable_sysTimerStart(); - if ((exitCode=portable_system("epstopdf",epstopdfArgs))!=0) + QDictIterator< QList<QCString> > it( plantumlFiles); // See QDictIterator + QList<QCString> *list; + for (it.toFirst();(list=it.current());++it) { - err("Problems running epstopdf. Check your TeX installation! Exit code: %d\n",exitCode); + Debug::print(Debug::Plantuml,0,"*** %s PlantumlFiles key:%s size:%d\n","PlantumlManager::print Files",qPrint(it.currentKey()),(*list).count()); + QListIterator<QCString> li(*list); + QCString *nb; + for (li.toFirst();(nb=li.current());++li) + { + Debug::print(Debug::Plantuml,0,"*** %s list:%s\n","PlantumlManager::print",qPrint(*nb)); + } } - portable_sysTimerStop(); } - Doxygen::indexList->addImageFile(imgName); } +static void print(const QDict<QCString> &plantumlContent) +{ + if (Debug::isFlagSet(Debug::Plantuml)) + { + QDictIterator< QCString > it( plantumlContent); // See QDictIterator + QCString *nb; + for (it.toFirst();(nb=it.current());++it) + { + Debug::print(Debug::Plantuml,0,"*** %s PlantumlContent key:%s\n","PlantumlManager::print Content",qPrint(it.currentKey())); + Debug::print(Debug::Plantuml,0,"*** %s Content :%s\n","PlantumlManager::print",qPrint(*nb)); + } + } +} + +static void addPlantumlFiles(QDict< QList<QCString> > &plantumlFiles, + const QCString &key , const QCString &value) +{ + QList<QCString> *list = plantumlFiles.find(key); + if (list==0) + { + list = new QList<QCString>; + plantumlFiles.insert(key,list); + } + list->append(new QCString(value)); +} + +static void addPlantumlContent(QDict< QCString > &plantumlContent, + const QCString &key, const QCString &puContent) +{ + QCString* content = plantumlContent.find(key); + if (content == 0) + { + content = new QCString(""); + plantumlContent.insert(key,content); + } + (*content)+=puContent; +} + + + +void PlantumlManager::insert(const QCString &key, const QCString &value, + OutputFormat format,const QCString &puContent) +{ + int find; + + Debug::print(Debug::Plantuml,0,"*** %s key:%s ,value:%s\n","PlantumlManager::insert",qPrint(key),qPrint(value)); + + m_currentPlantumlAllContent+=puContent; + + find = m_cachedPlantumlAllContent.find(puContent); + Debug::print(Debug::Plantuml,0,"*** %s find: %d\n","PlantumlManager::addPlantumlContent",find); + if (find >=0) + { // matched in cache. so we skip to run java for this plantuml + return ; + } + + switch (format) + { + case PUML_BITMAP: + addPlantumlFiles(m_pngPlantumlFiles,key,value); + print(m_pngPlantumlFiles); + addPlantumlContent(m_pngPlantumlContent,key,puContent); + print(m_pngPlantumlContent); + break; + case PUML_EPS: + addPlantumlFiles(m_epsPlantumlFiles,key,value); + print(m_epsPlantumlFiles); + addPlantumlContent(m_epsPlantumlContent,key,puContent); + print(m_epsPlantumlContent); + break; + case PUML_SVG: + addPlantumlFiles(m_svgPlantumlFiles,key,value); + print(m_svgPlantumlFiles); + addPlantumlContent(m_svgPlantumlContent,key,puContent); + print(m_svgPlantumlContent); + break; + } +} + +//-------------------------------------------------------------------- |