build: merge Coati app and Trial to single executable
* removed trial target * updated deploy scripts to exclude trial * cleanup CMakeLists * removed Eigen dependencies * split parser lib into lib_cxx and lib_java * added ProjectFactory and ProjectFactoryModules * removed old installer projects * updated wix installer * updated readme for wix setup * updated to use obfuscated exe * added qt.conf * added indexing dialog images * added jars * added coatidb files of sample projects * added source code of javaparser sample * removed auto-refresh image * intermediate files of windows installer are created in build folder * preselected desktop shortcut * build bat is executed from deploy_windows script
This commit is contained in:
@@ -121,6 +121,11 @@ Application::~Application()
|
||||
}
|
||||
}
|
||||
|
||||
void Application::addProjectFactoryModule(std::shared_ptr<ProjectFactoryModule> module)
|
||||
{
|
||||
m_projectFactory.addModule(module);
|
||||
}
|
||||
|
||||
const std::shared_ptr<Project> Application::getCurrentProject()
|
||||
{
|
||||
return m_project;
|
||||
@@ -155,7 +160,7 @@ void Application::createAndLoadProject(const FilePath& projectSettingsFilePath)
|
||||
|
||||
m_storageCache->clear();
|
||||
|
||||
m_project = Project::create(projectSettingsFilePath, m_storageCache.get(), getDialogView());
|
||||
m_project = m_projectFactory.createProject(projectSettingsFilePath, m_storageCache.get(), getDialogView());
|
||||
|
||||
if (m_project)
|
||||
{
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
#include <memory>
|
||||
|
||||
#include "component/ComponentManager.h"
|
||||
#include "Project.h"
|
||||
#include "utility/messaging/MessageListener.h"
|
||||
#include "utility/messaging/type/MessageActivateWindow.h"
|
||||
#include "utility/messaging/type/MessageFinishedParsing.h"
|
||||
#include "utility/messaging/type/MessageLoadProject.h"
|
||||
#include "utility/messaging/type/MessageRefresh.h"
|
||||
#include "utility/messaging/type/MessageSwitchColorScheme.h"
|
||||
#include "Project.h"
|
||||
#include "ProjectFactory.h"
|
||||
|
||||
class DialogView;
|
||||
class IDECommunicationController;
|
||||
@@ -19,6 +20,7 @@ class NetworkFactory;
|
||||
class StorageCache;
|
||||
class Version;
|
||||
class ViewFactory;
|
||||
class ProjectFactoryModule;
|
||||
|
||||
class Application
|
||||
: public MessageListener<MessageActivateWindow>
|
||||
@@ -35,12 +37,13 @@ public:
|
||||
static void loadSettings();
|
||||
static void loadStyle(const FilePath& colorSchemePath);
|
||||
|
||||
void addProjectFactoryModule(std::shared_ptr<ProjectFactoryModule> module);
|
||||
|
||||
~Application();
|
||||
|
||||
const std::shared_ptr<Project> getCurrentProject();
|
||||
|
||||
void createAndLoadProject(const FilePath& projectSettingsFilePath);
|
||||
void loadProject(const FilePath& projectSettingsFilePath);
|
||||
void refreshProject(bool force);
|
||||
bool hasGUI();
|
||||
|
||||
@@ -67,6 +70,7 @@ private:
|
||||
DialogView* getDialogView() const;
|
||||
|
||||
const bool m_hasGUI;
|
||||
ProjectFactory m_projectFactory;
|
||||
std::shared_ptr<Project> m_project;
|
||||
std::shared_ptr<StorageCache> m_storageCache;
|
||||
|
||||
|
||||
+10
-16
@@ -6,8 +6,6 @@ add_files(
|
||||
component/controller/helper/BucketGrid.h
|
||||
component/controller/helper/DummyEdge.h
|
||||
component/controller/helper/DummyNode.h
|
||||
component/controller/helper/GraphLayouter.cpp
|
||||
component/controller/helper/GraphLayouter.h
|
||||
component/controller/helper/GraphPostprocessor.cpp
|
||||
component/controller/helper/GraphPostprocessor.h
|
||||
component/controller/helper/NetworkProtocolHelper.cpp
|
||||
@@ -128,14 +126,8 @@ add_files(
|
||||
data/name/NameHierarchy.cpp
|
||||
data/name/NameHierarchy.h
|
||||
|
||||
data/parser/cxx/TaskParseCxx.h
|
||||
data/parser/cxx/TaskParseWrapper.h
|
||||
|
||||
data/parser/java/JavaEnvironment.cpp
|
||||
data/parser/java/JavaEnvironment.h
|
||||
data/parser/java/JavaEnvironmentFactory.cpp
|
||||
data/parser/java/JavaEnvironmentFactory.h
|
||||
data/parser/java/TaskParseJava.h
|
||||
data/parser/TaskParseWrapper.cpp
|
||||
data/parser/TaskParseWrapper.h
|
||||
|
||||
data/parser/AccessKind.cpp
|
||||
data/parser/AccessKind.h
|
||||
@@ -213,7 +205,10 @@ add_files(
|
||||
settings/Settings.h
|
||||
settings/SettingsMigrator.cpp
|
||||
settings/SettingsMigrator.h
|
||||
|
||||
|
||||
utility/commandline/CommandLineParser.cpp
|
||||
utility/commandline/CommandLineParser.h
|
||||
|
||||
utility/file/FileInfo.cpp
|
||||
utility/file/FileInfo.h
|
||||
utility/file/FileManager.cpp
|
||||
@@ -344,7 +339,6 @@ add_files(
|
||||
utility/AppPath.cpp
|
||||
utility/AppPath.h
|
||||
utility/Cache.h
|
||||
utility/CompilationDatabase.h
|
||||
utility/ConfigManager.cpp
|
||||
utility/ConfigManager.h
|
||||
utility/Property.h
|
||||
@@ -370,13 +364,13 @@ add_files(
|
||||
|
||||
Application.cpp
|
||||
Application.h
|
||||
CxxProject.cpp
|
||||
CxxProject.h
|
||||
isTrial.h
|
||||
JavaProject.cpp
|
||||
JavaProject.h
|
||||
LicenseChecker.cpp
|
||||
LicenseChecker.h
|
||||
Project.cpp
|
||||
Project.h
|
||||
ProjectFactory.cpp
|
||||
ProjectFactory.h
|
||||
ProjectFactoryModule.cpp
|
||||
ProjectFactoryModule.h
|
||||
)
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
#include "CxxProject.h"
|
||||
|
||||
#include "data/parser/cxx/TaskParseCxx.h"
|
||||
#include "settings/ApplicationSettings.h"
|
||||
|
||||
#include "utility/file/FileRegister.h"
|
||||
#include "utility/file/FileSystem.h"
|
||||
#include "utility/messaging/type/MessageStatus.h"
|
||||
#include "utility/utility.h"
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
CxxProject::~CxxProject()
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<ProjectSettings> CxxProject::getProjectSettings()
|
||||
{
|
||||
return m_projectSettings;
|
||||
}
|
||||
|
||||
const std::shared_ptr<ProjectSettings> CxxProject::getProjectSettings() const
|
||||
{
|
||||
return m_projectSettings;
|
||||
}
|
||||
|
||||
CxxProject::CxxProject(
|
||||
std::shared_ptr<CxxProjectSettings> projectSettings, StorageAccessProxy* storageAccessProxy, DialogView* dialogView
|
||||
)
|
||||
: Project(storageAccessProxy, dialogView)
|
||||
, m_projectSettings(projectSettings)
|
||||
{
|
||||
}
|
||||
|
||||
bool CxxProject::prepareRefresh()
|
||||
{
|
||||
FilePath cdbPath = m_projectSettings->getCompilationDatabasePath();
|
||||
if (!cdbPath.empty() && !cdbPath.exists())
|
||||
{
|
||||
MessageStatus("Can't refresh project").dispatch();
|
||||
|
||||
if (Application::getInstance()->hasGUI())
|
||||
{
|
||||
std::vector<std::string> options;
|
||||
options.push_back("Ok");
|
||||
Application::getInstance()->handleDialog(
|
||||
"Can't refresh. The compilation database of the project does not exist anymore: " + cdbPath.str(),
|
||||
options
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<Task> CxxProject::createIndexerTask(
|
||||
std::shared_ptr<StorageProvider> storageProvider,
|
||||
std::shared_ptr<FileRegister> fileRegister)
|
||||
{
|
||||
return std::make_shared<TaskParseCxx>(
|
||||
storageProvider,
|
||||
fileRegister,
|
||||
getParserArguments(),
|
||||
getDialogView()
|
||||
);
|
||||
}
|
||||
|
||||
void CxxProject::updateFileManager(FileManager& fileManager)
|
||||
{
|
||||
std::vector<FilePath> sourcePaths = m_projectSettings->getAbsoluteSourcePaths();
|
||||
std::vector<FilePath> headerPaths = sourcePaths;
|
||||
|
||||
std::vector<std::string> sourceExtensions;
|
||||
|
||||
if (m_projectSettings->getCompilationDatabasePath().exists())
|
||||
{
|
||||
sourcePaths = TaskParseCxx::getSourceFilesFromCDB(m_projectSettings->getCompilationDatabasePath());
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceExtensions = m_projectSettings->getSourceExtensions();
|
||||
}
|
||||
|
||||
std::vector<FilePath> excludePaths = m_projectSettings->getAbsoluteExcludePaths();
|
||||
|
||||
fileManager.setPaths(sourcePaths, headerPaths, excludePaths, sourceExtensions);
|
||||
}
|
||||
|
||||
Parser::Arguments CxxProject::getParserArguments() const
|
||||
{
|
||||
std::shared_ptr<ApplicationSettings> appSettings = ApplicationSettings::getInstance();
|
||||
|
||||
Parser::Arguments args;
|
||||
|
||||
utility::append(args.compilerFlags, m_projectSettings->getCompilerFlags());
|
||||
|
||||
// Add the source paths as HeaderSearchPaths as well, so clang will also look here when searching include files.
|
||||
for (const FilePath& sourcePath: getSourcePaths())
|
||||
{
|
||||
if (sourcePath.isDirectory())
|
||||
{
|
||||
args.systemHeaderSearchPaths.push_back(sourcePath);
|
||||
}
|
||||
}
|
||||
|
||||
utility::append(args.systemHeaderSearchPaths, m_projectSettings->getAbsoluteHeaderSearchPaths());
|
||||
|
||||
utility::append(args.systemHeaderSearchPaths, appSettings->getHeaderSearchPathsExpanded());
|
||||
|
||||
// Add all subdirectories of the header search paths
|
||||
if (m_projectSettings->getUseSourcePathsForHeaderSearch())
|
||||
{
|
||||
std::vector<FilePath> headerSearchSubPaths;
|
||||
for (FilePath p : m_projectSettings->getSourcePaths())
|
||||
{
|
||||
utility::append(headerSearchSubPaths, FileSystem::getSubDirectories(p));
|
||||
}
|
||||
|
||||
utility::append(args.systemHeaderSearchPaths, utility::unique(headerSearchSubPaths));
|
||||
}
|
||||
|
||||
utility::append(args.frameworkSearchPaths, m_projectSettings->getAbsoluteFrameworkSearchPaths());
|
||||
utility::append(args.frameworkSearchPaths, appSettings->getFrameworkSearchPathsExpanded());
|
||||
|
||||
args.language = languageTypeToString(m_projectSettings->getLanguage());
|
||||
args.languageStandard = m_projectSettings->getStandard();
|
||||
args.compilationDatabasePath = m_projectSettings->getCompilationDatabasePath();
|
||||
|
||||
return args;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
#ifndef CXX_PROJECT_H
|
||||
#define CXX_PROJECT_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "settings/CxxProjectSettings.h"
|
||||
#include "Project.h"
|
||||
|
||||
class CxxProject: public Project
|
||||
{
|
||||
public:
|
||||
virtual ~CxxProject();
|
||||
|
||||
protected:
|
||||
virtual std::shared_ptr<ProjectSettings> getProjectSettings();
|
||||
virtual const std::shared_ptr<ProjectSettings> getProjectSettings() const;
|
||||
|
||||
private:
|
||||
CxxProject(
|
||||
std::shared_ptr<CxxProjectSettings> projectSettings,
|
||||
StorageAccessProxy* storageAccessProxy,
|
||||
DialogView* dialogView
|
||||
);
|
||||
CxxProject(const CxxProject&);
|
||||
|
||||
virtual bool prepareRefresh();
|
||||
|
||||
virtual std::shared_ptr<Task> createIndexerTask(
|
||||
std::shared_ptr<StorageProvider> storageProvider,
|
||||
std::shared_ptr<FileRegister> fileRegister);
|
||||
|
||||
virtual void updateFileManager(FileManager& fileManager);
|
||||
|
||||
Parser::Arguments getParserArguments() const;
|
||||
|
||||
std::shared_ptr<CxxProjectSettings> m_projectSettings;
|
||||
|
||||
|
||||
friend Project;
|
||||
};
|
||||
|
||||
#endif // CXX_PROJECT_H
|
||||
@@ -1,116 +0,0 @@
|
||||
#include "JavaProject.h"
|
||||
|
||||
#include "data/parser/java/JavaEnvironmentFactory.h"
|
||||
#include "data/parser/java/TaskParseJava.h"
|
||||
#include "utility/messaging/type/MessageStatus.h"
|
||||
#include "utility/ResourcePaths.h"
|
||||
#include "Application.h"
|
||||
#include "isTrial.h"
|
||||
|
||||
JavaProject::~JavaProject()
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<ProjectSettings> JavaProject::getProjectSettings()
|
||||
{
|
||||
return m_projectSettings;
|
||||
}
|
||||
|
||||
const std::shared_ptr<ProjectSettings> JavaProject::getProjectSettings() const
|
||||
{
|
||||
return m_projectSettings;
|
||||
}
|
||||
|
||||
JavaProject::JavaProject(
|
||||
std::shared_ptr<JavaProjectSettings> projectSettings, StorageAccessProxy* storageAccessProxy, DialogView* dialogView
|
||||
)
|
||||
: Project(storageAccessProxy, dialogView)
|
||||
, m_projectSettings(projectSettings)
|
||||
{
|
||||
}
|
||||
|
||||
bool JavaProject::prepareIndexing()
|
||||
{
|
||||
std::string errorString;
|
||||
if (!JavaEnvironmentFactory::getInstance() && !isTrial())
|
||||
{
|
||||
#ifdef _WIN32
|
||||
const std::string separator = ";";
|
||||
#else
|
||||
const std::string separator = ":";
|
||||
#endif
|
||||
JavaEnvironmentFactory::createInstance(
|
||||
ResourcePaths::getJavaPath() + "guava-18.0.jar" + separator +
|
||||
ResourcePaths::getJavaPath() + "java-indexer.jar" + separator +
|
||||
ResourcePaths::getJavaPath() + "javaparser-core.jar" + separator +
|
||||
ResourcePaths::getJavaPath() + "javaslang-2.0.0-beta.jar" + separator +
|
||||
ResourcePaths::getJavaPath() + "javassist-3.19.0-GA.jar" + separator +
|
||||
ResourcePaths::getJavaPath() + "java-symbol-solver-core.jar" + separator +
|
||||
ResourcePaths::getJavaPath() + "java-symbol-solver-logic.jar" + separator +
|
||||
ResourcePaths::getJavaPath() + "java-symbol-solver-model.jar",
|
||||
errorString
|
||||
);
|
||||
}
|
||||
|
||||
if (errorString.size() > 0)
|
||||
{
|
||||
LOG_ERROR(errorString);
|
||||
MessageStatus(errorString, true, false).dispatch();
|
||||
}
|
||||
|
||||
if (!JavaEnvironmentFactory::getInstance() && !isTrial())
|
||||
{
|
||||
std::string dialogMessage =
|
||||
"Coati was unable to locate Java on this machine.\nPlease make sure to provide the correct Java Path in the preferences.";
|
||||
|
||||
if (errorString.size() > 0)
|
||||
{
|
||||
dialogMessage += "\n\nError: " + errorString;
|
||||
}
|
||||
|
||||
Application::getInstance()->handleDialog(dialogMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<Task> JavaProject::createIndexerTask(
|
||||
std::shared_ptr<StorageProvider> storageProvider,
|
||||
std::shared_ptr<FileRegister> fileRegister)
|
||||
{
|
||||
Parser::Arguments arguments;
|
||||
|
||||
for (FilePath classpath: m_projectSettings->getAbsoluteClasspaths())
|
||||
{
|
||||
if (classpath.exists())
|
||||
{
|
||||
arguments.javaClassPaths.push_back(classpath.str());
|
||||
}
|
||||
}
|
||||
|
||||
for (FilePath sourcePath: m_projectSettings->getAbsoluteSourcePaths())
|
||||
{
|
||||
if (sourcePath.extension().empty() && sourcePath.exists())
|
||||
{
|
||||
arguments.javaClassPaths.push_back(sourcePath.str());
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_shared<TaskParseJava>(
|
||||
storageProvider,
|
||||
fileRegister,
|
||||
arguments,
|
||||
getDialogView()
|
||||
);
|
||||
}
|
||||
|
||||
void JavaProject::updateFileManager(FileManager& fileManager)
|
||||
{
|
||||
std::vector<FilePath> sourcePaths = m_projectSettings->getAbsoluteSourcePaths();
|
||||
std::vector<FilePath> headerPaths = sourcePaths;
|
||||
std::vector<std::string> sourceExtensions = m_projectSettings->getSourceExtensions();
|
||||
std::vector<FilePath> excludePaths = m_projectSettings->getAbsoluteExcludePaths();
|
||||
|
||||
fileManager.setPaths(sourcePaths, headerPaths, excludePaths, sourceExtensions);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
#ifndef JAVA_PROJECT_H
|
||||
#define JAVA_PROJECT_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "settings/JavaProjectSettings.h"
|
||||
#include "Project.h"
|
||||
|
||||
class JavaProject: public Project
|
||||
{
|
||||
public:
|
||||
virtual ~JavaProject();
|
||||
|
||||
protected:
|
||||
virtual std::shared_ptr<ProjectSettings> getProjectSettings();
|
||||
virtual const std::shared_ptr<ProjectSettings> getProjectSettings() const;
|
||||
|
||||
private:
|
||||
JavaProject(
|
||||
std::shared_ptr<JavaProjectSettings> projectSettings,
|
||||
StorageAccessProxy* storageAccessProxy,
|
||||
DialogView* dialogView
|
||||
);
|
||||
JavaProject(const JavaProject&);
|
||||
|
||||
virtual bool prepareIndexing();
|
||||
|
||||
virtual std::shared_ptr<Task> createIndexerTask(
|
||||
std::shared_ptr<StorageProvider> storageProvider,
|
||||
std::shared_ptr<FileRegister> fileRegister);
|
||||
|
||||
virtual void updateFileManager(FileManager& fileManager);
|
||||
|
||||
std::shared_ptr<JavaProjectSettings> m_projectSettings;
|
||||
|
||||
friend Project;
|
||||
};
|
||||
|
||||
#endif // JAVA_PROJECT_H
|
||||
+1
-34
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "component/view/DialogView.h"
|
||||
#include "data/access/StorageAccessProxy.h"
|
||||
#include "data/parser/cxx/TaskParseWrapper.h"
|
||||
#include "data/parser/TaskParseWrapper.h"
|
||||
#include "data/parser/java/TaskParseJava.h"
|
||||
#include "data/StorageProvider.h"
|
||||
#include "data/PersistentStorage.h"
|
||||
@@ -28,39 +28,6 @@
|
||||
#include "JavaProject.h"
|
||||
#include "isTrial.h"
|
||||
|
||||
std::shared_ptr<Project> Project::create(
|
||||
const FilePath& projectSettingsFile, StorageAccessProxy* storageAccessProxy, DialogView* dialogView)
|
||||
{
|
||||
std::shared_ptr<Project> project;
|
||||
|
||||
switch (ProjectSettings::getLanguageOfProject(projectSettingsFile))
|
||||
{
|
||||
case LANGUAGE_C:
|
||||
case LANGUAGE_CPP:
|
||||
{
|
||||
project = std::shared_ptr<CxxProject>(new CxxProject(
|
||||
std::make_shared<CxxProjectSettings>(projectSettingsFile), storageAccessProxy, dialogView
|
||||
));
|
||||
}
|
||||
break;
|
||||
case LANGUAGE_JAVA:
|
||||
{
|
||||
project = std::shared_ptr<JavaProject>(new JavaProject(
|
||||
std::make_shared<JavaProjectSettings>(projectSettingsFile), storageAccessProxy, dialogView
|
||||
));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (project)
|
||||
{
|
||||
project->load();
|
||||
}
|
||||
return project;
|
||||
}
|
||||
|
||||
Project::~Project()
|
||||
{
|
||||
}
|
||||
|
||||
+3
-3
@@ -20,9 +20,6 @@ class Task;
|
||||
class Project
|
||||
{
|
||||
public:
|
||||
static std::shared_ptr<Project> create(
|
||||
const FilePath& projectSettingsFile, StorageAccessProxy* storageAccessProxy, DialogView* dialogView);
|
||||
|
||||
virtual ~Project();
|
||||
|
||||
bool refresh(bool forceRefresh);
|
||||
@@ -58,7 +55,10 @@ private:
|
||||
|
||||
Project(const Project&);
|
||||
|
||||
public: // todo: make private again
|
||||
void load();
|
||||
|
||||
private:
|
||||
bool buildIndex(bool forceRefresh);
|
||||
|
||||
virtual bool prepareIndexing();
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "ProjectFactory.h"
|
||||
|
||||
#include "component/view/DialogView.h"
|
||||
#include "data/access/StorageAccessProxy.h"
|
||||
#include "settings/ProjectSettings.h"
|
||||
#include "utility/file/FilePath.h"
|
||||
|
||||
#include "Project.h"
|
||||
#include "ProjectFactoryModule.h"
|
||||
|
||||
void ProjectFactory::addModule(std::shared_ptr<ProjectFactoryModule> module)
|
||||
{
|
||||
m_modules[module->getLanguage()] = module;
|
||||
}
|
||||
|
||||
std::shared_ptr<Project> ProjectFactory::createProject(
|
||||
const FilePath& projectSettingsFile, StorageAccessProxy* storageAccessProxy, DialogView* dialogView)
|
||||
{
|
||||
std::shared_ptr<Project> project;
|
||||
|
||||
std::map<LanguageType, std::shared_ptr<ProjectFactoryModule>>::const_iterator it = m_modules.find(
|
||||
ProjectSettings::getLanguageOfProject(projectSettingsFile)
|
||||
);
|
||||
|
||||
if (it != m_modules.end())
|
||||
{
|
||||
project = it->second->createProject(projectSettingsFile, storageAccessProxy, dialogView);
|
||||
}
|
||||
|
||||
if (project)
|
||||
{
|
||||
project->load();
|
||||
}
|
||||
return project;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef PROJECT_FACTORY_H
|
||||
#define PROJECT_FACTORY_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "settings/LanguageType.h"
|
||||
|
||||
class Project;
|
||||
class FilePath;
|
||||
class StorageAccessProxy;
|
||||
class DialogView;
|
||||
class ProjectFactoryModule;
|
||||
|
||||
class ProjectFactory
|
||||
{
|
||||
public:
|
||||
void addModule(std::shared_ptr<ProjectFactoryModule> module);
|
||||
|
||||
std::shared_ptr<Project> createProject(
|
||||
const FilePath& projectSettingsFile, StorageAccessProxy* storageAccessProxy, DialogView* dialogView);
|
||||
|
||||
private:
|
||||
std::map<LanguageType, std::shared_ptr<ProjectFactoryModule>> m_modules;
|
||||
};
|
||||
|
||||
#endif // PROJECT_FACTORY_H
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "ProjectFactoryModule.h"
|
||||
|
||||
ProjectFactoryModule::~ProjectFactoryModule()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef PROJECT_FACTORY_MODULE_H
|
||||
#define PROJECT_FACTORY_MODULE_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "settings/LanguageType.h"
|
||||
|
||||
class Project;
|
||||
class FilePath;
|
||||
class StorageAccessProxy;
|
||||
class DialogView;
|
||||
|
||||
class ProjectFactoryModule
|
||||
{
|
||||
public:
|
||||
virtual ~ProjectFactoryModule();
|
||||
virtual LanguageType getLanguage() const = 0;
|
||||
|
||||
virtual std::shared_ptr<Project> createProject(
|
||||
const FilePath& projectSettingsFile, StorageAccessProxy* storageAccessProxy, DialogView* dialogView
|
||||
) = 0;
|
||||
};
|
||||
|
||||
#endif // PROJECT_FACTORY_MODULE_H
|
||||
@@ -1,255 +0,0 @@
|
||||
#include "component/controller/helper/GraphLayouter.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
|
||||
#include "component/controller/helper/DummyEdge.h"
|
||||
#include "component/controller/helper/DummyNode.h"
|
||||
#include "data/graph/Node.h"
|
||||
|
||||
// for prototyping, remove when done
|
||||
#include "Eigen/Dense"
|
||||
#include "Eigen/Eigenvalues"
|
||||
#include "unsupported/Eigen/MatrixFunctions"
|
||||
|
||||
bool compareEigenvaluePairs(const std::pair<int, double>& p0, const std::pair<int, double>& p1)
|
||||
{
|
||||
return p0.second > p1.second;
|
||||
}
|
||||
|
||||
void GraphLayouter::layoutSimpleRaster(std::vector<DummyNode>& nodes)
|
||||
{
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int offset = 150;
|
||||
|
||||
int w = ceil(sqrt(nodes.size()));
|
||||
|
||||
for (unsigned int i = 0; i < nodes.size(); i++)
|
||||
{
|
||||
if (i > 0 && i % w == 0)
|
||||
{
|
||||
y += offset;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
nodes[i].position = Vec2i(x, y);
|
||||
|
||||
x += offset;
|
||||
}
|
||||
}
|
||||
|
||||
void GraphLayouter::layoutSimpleRing(std::vector<DummyNode>& nodes)
|
||||
{
|
||||
if (nodes.size() >= 1)
|
||||
{
|
||||
nodes[0].position = Vec2i(0, 0);
|
||||
|
||||
if (nodes.size() > 1)
|
||||
{
|
||||
float offset = 200.0f;
|
||||
|
||||
for (unsigned int i = 1; i < nodes.size(); i++)
|
||||
{
|
||||
float rad = 2.0f * 3.14159265359f / float(nodes.size() - 1) * i - 1;
|
||||
|
||||
int x = offset * std::cos(rad);
|
||||
int y = offset * std::sin(rad);
|
||||
|
||||
nodes[i].position = Vec2i(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GraphLayouter::layoutSpectralPrototype(std::vector<DummyNode>& nodes, const std::vector<DummyEdge>& edges)
|
||||
{
|
||||
if (nodes.size() < 2)
|
||||
{
|
||||
LOG_INFO("Not enough nodes for layouting");
|
||||
return;
|
||||
}
|
||||
|
||||
MatrixDynamicBase<int> laplacian = buildLaplacianMatrix(nodes, edges);
|
||||
|
||||
// If the laplacian matrix has a zero value in it's diagonal, that means there are unconnected nodes and the spectral
|
||||
// layouting fails for some reason. In this case we switch to raster layout.
|
||||
for (unsigned int i = 0; i < laplacian.getColumnsCount(); i++)
|
||||
{
|
||||
if (laplacian.getValue(i, i) == 0)
|
||||
{
|
||||
layoutSimpleRaster(nodes);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Eigen::MatrixXd degreeMatrix = Eigen::MatrixXd::Zero(laplacian.getColumnsCount(), laplacian.getRowsCount());
|
||||
Eigen::MatrixXd eigenMatrix = Eigen::MatrixXd::Zero(laplacian.getColumnsCount(), laplacian.getRowsCount());
|
||||
|
||||
for(unsigned int x = 0; x < laplacian.getColumnsCount(); x++)
|
||||
{
|
||||
for(unsigned int y = 0; y < laplacian.getRowsCount(); y++)
|
||||
{
|
||||
eigenMatrix(x, y) = laplacian.getValue(x, y);
|
||||
|
||||
if(x == y)
|
||||
{
|
||||
degreeMatrix(x, y) = laplacian.getValue(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
degreeMatrix = degreeMatrix.inverse();
|
||||
Eigen::MatrixPower<Eigen::MatrixXd> dPow(degreeMatrix);
|
||||
degreeMatrix = dPow(0.5);
|
||||
|
||||
eigenMatrix = degreeMatrix * eigenMatrix * degreeMatrix;
|
||||
|
||||
eigenMatrix.normalize();
|
||||
Eigen::EigenSolver<Eigen::MatrixXd> solver(eigenMatrix);
|
||||
|
||||
std::vector<std::vector<double>> eigenVectors;
|
||||
for(unsigned int i = 0; i < solver.eigenvectors().cols(); i++)
|
||||
{
|
||||
eigenVectors.push_back(std::vector<double>());
|
||||
|
||||
for(unsigned int j = 0; j < solver.eigenvectors().rows(); j++)
|
||||
{
|
||||
eigenVectors[i].push_back(solver.eigenvectors()(i*solver.eigenvectors().rows() + j).real());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::pair<int, double>> eigenValues;
|
||||
for(unsigned int i = 0; i < solver.eigenvalues().size(); i++)
|
||||
{
|
||||
eigenValues.push_back(std::pair<int, double>(i, solver.eigenvalues()(i).real()));
|
||||
}
|
||||
|
||||
std::sort(eigenValues.begin(), eigenValues.end(), compareEigenvaluePairs);
|
||||
|
||||
if(eigenVectors.size() > 0 && eigenVectors[0].size() >= 3)
|
||||
{
|
||||
unsigned int xIdx = eigenValues[eigenValues.size()-2].first;
|
||||
unsigned int yIdx = eigenValues[eigenValues.size()-3].first;
|
||||
|
||||
/*double xEigenValue = std::sqrt(solver.eigenvalues()(xIdx).real());
|
||||
double yEigenValue = std::sqrt(solver.eigenvalues()(yIdx).real());*/
|
||||
|
||||
for(unsigned int i = 0; i < nodes.size(); i++)
|
||||
{
|
||||
float xPos = eigenVectors[xIdx][i];
|
||||
float yPos = eigenVectors[yIdx][i];
|
||||
|
||||
Vec2f newPos(xPos, yPos);
|
||||
|
||||
newPos.normalize();
|
||||
newPos *= 600.0f;
|
||||
|
||||
nodes[i].position.x = newPos.x;
|
||||
nodes[i].position.y = newPos.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MatrixDynamicBase<int> GraphLayouter::buildLaplacianMatrix(
|
||||
const std::vector<DummyNode>& nodes, const std::vector<DummyEdge>& edges)
|
||||
{
|
||||
MatrixDynamicBase<int> matrix(nodes.size(), nodes.size());
|
||||
|
||||
std::map<Id, DummyNode> nodesMap;
|
||||
std::queue<DummyNode> remainingNodes;
|
||||
for(unsigned int i = 0; i < nodes.size(); i++)
|
||||
{
|
||||
remainingNodes.push(nodes[i]);
|
||||
}
|
||||
|
||||
while(remainingNodes.size() > 0)
|
||||
{
|
||||
if(remainingNodes.front().subNodes.size() > 0)
|
||||
{
|
||||
for(unsigned int i = 0; i < remainingNodes.front().subNodes.size(); i++)
|
||||
{
|
||||
remainingNodes.push(*remainingNodes.front().subNodes[i].get());
|
||||
}
|
||||
}
|
||||
|
||||
nodesMap[remainingNodes.front().tokenId] = remainingNodes.front();
|
||||
remainingNodes.pop();
|
||||
}
|
||||
|
||||
std::map<std::pair<Id, Id>, int> weightsMap;
|
||||
for(unsigned int i = 0; i < edges.size(); i++)
|
||||
{
|
||||
const DummyEdge& edge = edges[i];
|
||||
DummyNode ownerNode = nodesMap[edge.ownerId];
|
||||
DummyNode targetNode = nodesMap[edge.targetId];
|
||||
|
||||
if(ownerNode.topLevelAncestorId != targetNode.topLevelAncestorId)
|
||||
{
|
||||
int weightIncrement = edge.getWeight();
|
||||
|
||||
Id ownerId = ownerNode.topLevelAncestorId;
|
||||
Id targetId = targetNode.topLevelAncestorId;
|
||||
std::pair<Id, Id> key(ownerId, targetId);
|
||||
std::pair<Id, Id> inverseKey(targetId, ownerId);
|
||||
std::pair<Id, Id> keyOwner(ownerId, ownerId);
|
||||
std::pair<Id, Id> keyTarget(targetId, targetId);
|
||||
|
||||
std::map<std::pair<Id, Id>, int>::iterator it = weightsMap.find(key);
|
||||
if(it == weightsMap.end())
|
||||
{
|
||||
weightsMap[key] = 0;
|
||||
}
|
||||
|
||||
weightsMap[key] += weightIncrement;
|
||||
|
||||
it = weightsMap.find(inverseKey);
|
||||
if(it == weightsMap.end())
|
||||
{
|
||||
weightsMap[inverseKey] = 0;
|
||||
}
|
||||
|
||||
weightsMap[inverseKey] += weightIncrement;
|
||||
|
||||
it = weightsMap.find(keyOwner);
|
||||
if(it == weightsMap.end())
|
||||
{
|
||||
weightsMap[keyOwner] = 0;
|
||||
}
|
||||
|
||||
weightsMap[keyOwner] += weightIncrement;
|
||||
|
||||
it = weightsMap.find(keyTarget);
|
||||
if(it == weightsMap.end())
|
||||
{
|
||||
weightsMap[keyTarget] = 0;
|
||||
}
|
||||
|
||||
weightsMap[keyTarget] += weightIncrement;
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned int x = 0; x < nodes.size(); x++)
|
||||
{
|
||||
for(unsigned int y = x; y < nodes.size(); y++)
|
||||
{
|
||||
unsigned int xNodeId = nodes[x].tokenId;
|
||||
unsigned int yNodeId = nodes[y].tokenId;
|
||||
|
||||
std::pair<Id, Id> key(xNodeId, yNodeId);
|
||||
|
||||
if(x == y)
|
||||
{
|
||||
matrix.setValue(x, y, weightsMap[key]);
|
||||
}
|
||||
else
|
||||
{
|
||||
matrix.setValue(x, y, -weightsMap[key]);
|
||||
matrix.setValue(y, x, -weightsMap[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matrix;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#ifndef GRAPH_LAYOUTER_H
|
||||
#define GRAPH_LAYOUTER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "utility/math/MatrixDynamicBase.h"
|
||||
#include "utility/math/Vector2.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
struct DummyEdge;
|
||||
struct DummyNode;
|
||||
|
||||
class GraphLayouter
|
||||
{
|
||||
public:
|
||||
static void layoutSimpleRaster(std::vector<DummyNode>& nodes);
|
||||
static void layoutSimpleRing(std::vector<DummyNode>& nodes);
|
||||
|
||||
static void layoutSpectralPrototype(std::vector<DummyNode>& nodes, const std::vector<DummyEdge>& edges);
|
||||
|
||||
private:
|
||||
static MatrixDynamicBase<int> buildLaplacianMatrix(
|
||||
const std::vector<DummyNode>& nodes, const std::vector<DummyEdge>& edges);
|
||||
};
|
||||
|
||||
#endif // GRAPH_LAYOUTER_H
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "data/graph/token_component/TokenComponentAccess.h"
|
||||
|
||||
#include "data/DefinitionType.h"
|
||||
#include "data/SqliteStorage.h"
|
||||
|
||||
class ParserClientImpl: public ParserClient
|
||||
{
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
#include "data/parser/TaskParseWrapper.h"
|
||||
|
||||
#include "component/view/DialogView.h"
|
||||
#include "data/PersistentStorage.h"
|
||||
#include "utility/file/FileRegister.h"
|
||||
#include "utility/messaging/type/MessageFinishedParsing.h"
|
||||
#include "utility/scheduling/Blackboard.h"
|
||||
#include "utility/utility.h"
|
||||
|
||||
TaskParseWrapper::TaskParseWrapper(
|
||||
PersistentStorage* storage,
|
||||
std::shared_ptr<FileRegister> fileRegister,
|
||||
DialogView* dialogView
|
||||
)
|
||||
: m_storage(storage)
|
||||
, m_fileRegister(fileRegister)
|
||||
, m_dialogView(dialogView)
|
||||
{
|
||||
}
|
||||
|
||||
TaskParseWrapper::~TaskParseWrapper()
|
||||
{
|
||||
}
|
||||
|
||||
void TaskParseWrapper::setTask(std::shared_ptr<Task> task)
|
||||
{
|
||||
if (task)
|
||||
{
|
||||
m_taskRunner = std::make_shared<TaskRunner>(task);
|
||||
}
|
||||
}
|
||||
|
||||
void TaskParseWrapper::doEnter(std::shared_ptr<Blackboard> blackboard)
|
||||
{
|
||||
blackboard->set("indexer_count", 0);
|
||||
m_dialogView->updateIndexingDialog(0, m_fileRegister->getSourceFilesCount(), "");
|
||||
|
||||
m_start = utility::durationStart();
|
||||
m_storage->startParsing();
|
||||
}
|
||||
|
||||
Task::TaskState TaskParseWrapper::doUpdate(std::shared_ptr<Blackboard> blackboard)
|
||||
{
|
||||
return m_taskRunner->update(blackboard);
|
||||
}
|
||||
|
||||
void TaskParseWrapper::doExit(std::shared_ptr<Blackboard> blackboard)
|
||||
{
|
||||
blackboard->clear("indexer_count");
|
||||
|
||||
m_dialogView->showProgressDialog("Finish Indexing", "Optimizing database");
|
||||
|
||||
m_storage->optimizeMemory();
|
||||
|
||||
m_dialogView->showProgressDialog("Finish Indexing", "Building caches");
|
||||
|
||||
m_storage->finishParsing();
|
||||
|
||||
m_dialogView->hideProgressDialog();
|
||||
|
||||
MessageFinishedParsing().dispatch();
|
||||
|
||||
m_dialogView->finishedIndexingDialog(
|
||||
m_fileRegister->getParsedSourceFilesCount(),
|
||||
m_fileRegister->getSourceFilesCount(),
|
||||
utility::duration(m_start),
|
||||
m_storage->getErrorCount()
|
||||
);
|
||||
}
|
||||
|
||||
void TaskParseWrapper::doReset(std::shared_ptr<Blackboard> blackboard)
|
||||
{
|
||||
m_taskRunner->reset();
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
#ifndef TASK_PARSE_CXX_H
|
||||
#define TASK_PARSE_CXX_H
|
||||
|
||||
#include <memory>
|
||||
#include <deque>
|
||||
|
||||
#include "data/parser/Parser.h"
|
||||
#include "data/parser/ParserClientImpl.h"
|
||||
#include "utility/scheduling/Task.h"
|
||||
#include "utility/TimePoint.h"
|
||||
#include "utility/messaging/type/MessageInterruptTasks.h"
|
||||
#include "utility/messaging/MessageListener.h"
|
||||
|
||||
class CxxParser;
|
||||
class DialogView;
|
||||
class FileRegister;
|
||||
class StorageProvider;
|
||||
|
||||
namespace clang
|
||||
{
|
||||
namespace tooling
|
||||
{
|
||||
class JSONCompilationDatabase;
|
||||
}
|
||||
}
|
||||
|
||||
class TaskParseCxx
|
||||
: public Task
|
||||
, public MessageListener<MessageInterruptTasks>
|
||||
{
|
||||
public:
|
||||
static std::vector<FilePath> getSourceFilesFromCDB(const FilePath& compilationDatabasePath);
|
||||
|
||||
TaskParseCxx(
|
||||
std::shared_ptr<StorageProvider> storageProvider,
|
||||
std::shared_ptr<FileRegister> fileRegister,
|
||||
const Parser::Arguments& arguments,
|
||||
DialogView* dialogView
|
||||
);
|
||||
|
||||
private:
|
||||
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
|
||||
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
|
||||
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
|
||||
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
|
||||
|
||||
virtual void handleMessage(MessageInterruptTasks* message);
|
||||
|
||||
std::shared_ptr<StorageProvider> m_storageProvider;
|
||||
|
||||
const Parser::Arguments m_arguments;
|
||||
DialogView* m_dialogView;
|
||||
|
||||
std::shared_ptr<CxxParser> m_parser;
|
||||
std::shared_ptr<ParserClientImpl> m_parserClient;
|
||||
|
||||
bool m_isCDB;
|
||||
std::shared_ptr<clang::tooling::JSONCompilationDatabase> m_cdb;
|
||||
|
||||
bool m_interrupted;
|
||||
};
|
||||
|
||||
#endif // TASK_PARSE_CXX_H
|
||||
@@ -1,92 +0,0 @@
|
||||
#include "data/parser/java/JavaEnvironment.h"
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
#include "data/parser/java/JavaEnvironmentFactory.h"
|
||||
|
||||
JavaEnvironment::~JavaEnvironment()
|
||||
{
|
||||
JavaEnvironmentFactory::getInstance()->unregisterEnvironment();
|
||||
}
|
||||
|
||||
bool JavaEnvironment::callStaticVoidMethod(std::string className, std::string methodName, int arg1, std::string arg2, std::string arg3, std::string arg4)
|
||||
{
|
||||
jclass javaClass = m_env->FindClass(className.c_str());
|
||||
if(javaClass == nullptr)
|
||||
{
|
||||
LOG_ERROR("class " + className + " not found in JVM environment");
|
||||
jthrowable exc = m_env->ExceptionOccurred();
|
||||
if(exc)
|
||||
{
|
||||
m_env->ExceptionDescribe();
|
||||
m_env->ExceptionClear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
jmethodID javaMethodId = m_env->GetStaticMethodID(javaClass, methodName.c_str(), "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
|
||||
if(javaMethodId == nullptr)
|
||||
{
|
||||
LOG_ERROR("method void " + methodName + "(int, String, String, String) not found in JVM environment");
|
||||
}
|
||||
else
|
||||
{
|
||||
jint jarg1 = arg1;
|
||||
jstring jarg2 = m_env->NewStringUTF(arg2.c_str());
|
||||
jstring jarg3 = m_env->NewStringUTF(arg3.c_str());
|
||||
jstring jarg4 = m_env->NewStringUTF(arg4.c_str());
|
||||
m_env->CallStaticVoidMethod(javaClass, javaMethodId, jarg1, jarg2, jarg3, jarg4);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string JavaEnvironment::toStdString(jstring s)
|
||||
{
|
||||
const char *nativeString = m_env->GetStringUTFChars(s, 0);
|
||||
std::string ret = nativeString;
|
||||
m_env->ReleaseStringUTFChars(s, nativeString);
|
||||
return ret;
|
||||
}
|
||||
|
||||
jstring JavaEnvironment::toJString(std::string s)
|
||||
{
|
||||
return m_env->NewStringUTF(s.c_str());
|
||||
}
|
||||
|
||||
JavaEnvironment::JavaEnvironment(JavaVM* jvm, JNIEnv* env)
|
||||
: m_jvm(jvm)
|
||||
, m_env(env)
|
||||
{
|
||||
JavaEnvironmentFactory::getInstance()->registerEnvironment();
|
||||
}
|
||||
|
||||
void JavaEnvironment::registerNativeMethods(std::string className, std::vector<NativeMethod> methods)
|
||||
{
|
||||
JNINativeMethod* jniMethods = new JNINativeMethod[methods.size()];
|
||||
|
||||
for (size_t i = 0; i < methods.size(); i++)
|
||||
{
|
||||
jniMethods[i].name = const_cast<char*>(methods[i].name.c_str());
|
||||
jniMethods[i].signature = const_cast<char*>(methods[i].signature.c_str());
|
||||
jniMethods[i].fnPtr = methods[i].function;
|
||||
}
|
||||
|
||||
jclass javaClass = m_env->FindClass(className.c_str());
|
||||
if (javaClass)
|
||||
{
|
||||
if (m_env->RegisterNatives(javaClass, jniMethods, methods.size()) < 0)
|
||||
{
|
||||
LOG_ERROR("RegisterNatives failed");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("class \"" + className + "\" not found while registering native methods");
|
||||
}
|
||||
|
||||
delete [] jniMethods;
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
#ifndef JAVA_ENVIRONMENT_H
|
||||
#define JAVA_ENVIRONMENT_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct JavaVM_;
|
||||
typedef JavaVM_ JavaVM;
|
||||
|
||||
struct JNIEnv_;
|
||||
typedef JNIEnv_ JNIEnv;
|
||||
|
||||
class _jstring;
|
||||
typedef _jstring *jstring;
|
||||
|
||||
class JavaEnvironmentFactory;
|
||||
|
||||
class JavaEnvironment
|
||||
{
|
||||
public:
|
||||
struct NativeMethod
|
||||
{
|
||||
std::string name;
|
||||
std::string signature;
|
||||
void *function;
|
||||
};
|
||||
|
||||
~JavaEnvironment();
|
||||
bool callStaticVoidMethod(std::string className, std::string methodName, int arg1, std::string arg2, std::string arg3, std::string arg4);
|
||||
|
||||
std::string toStdString(jstring s);
|
||||
jstring toJString(std::string s);
|
||||
|
||||
void registerNativeMethods(std::string className, std::vector<NativeMethod> methods);
|
||||
private:
|
||||
friend class JavaEnvironmentFactory;
|
||||
|
||||
JavaEnvironment(JavaVM* jvm, JNIEnv* env);
|
||||
|
||||
JavaVM* m_jvm;
|
||||
JNIEnv* m_env;
|
||||
};
|
||||
|
||||
#endif // JAVA_ENVIRONMENT_H
|
||||
@@ -1,177 +0,0 @@
|
||||
#include "data/parser/java/JavaEnvironmentFactory.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "data/parser/java/JavaEnvironment.h"
|
||||
#include "settings/ApplicationSettings.h"
|
||||
#include "utility/file/FileSystem.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/utilityLibrary.h"
|
||||
|
||||
void JavaEnvironmentFactory::createInstance(std::string classPath, std::string& errorString)
|
||||
{
|
||||
if (s_instance)
|
||||
{
|
||||
if (classPath == s_classPath)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("java classpath cannot be changed!");
|
||||
// todo: implement destroying the old factory instance and create a new one.
|
||||
// may be not so easy... there can only be one java env per process (which can never be destroyed) -.-
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::function<jint (JavaVM**, void**, void*)> createInstanceFunction;
|
||||
|
||||
createInstanceFunction = utility::loadFunctionFromLibrary<jint, JavaVM**, void**, void*>(
|
||||
FilePath(ApplicationSettings::getInstance()->getJavaPath()),
|
||||
"JNI_CreateJavaVM",
|
||||
errorString
|
||||
);
|
||||
|
||||
if (!createInstanceFunction && errorString.size() > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
s_classPath = classPath;
|
||||
|
||||
JavaVM* jvm = nullptr; // Pointer to the JVM (Java Virtual Machine)
|
||||
JNIEnv* env = nullptr; // Pointer to native interface
|
||||
|
||||
JavaVMInitArgs vm_args; // Initialization arguments
|
||||
JavaVMOption* options = new JavaVMOption[3]; // JVM invocation options
|
||||
std::string classPathOption = "-Djava.class.path=" + classPath;
|
||||
options[0].optionString = const_cast<char*>(classPathOption.c_str());
|
||||
options[1].optionString = const_cast<char*>("-Xms64m");
|
||||
std::string maximumMemoryOprionString = "-Xmx" + std::to_string(ApplicationSettings::getInstance()->getJavaMaximumMemory()) + "m";
|
||||
options[2].optionString = const_cast<char*>(maximumMemoryOprionString.c_str());
|
||||
vm_args.version = JNI_VERSION_1_6;
|
||||
vm_args.nOptions = 3;
|
||||
vm_args.options = options;
|
||||
vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail
|
||||
|
||||
jint rc = createInstanceFunction(&jvm, (void**)&env, &vm_args);
|
||||
|
||||
delete [] options;
|
||||
|
||||
if (rc != JNI_OK)
|
||||
{
|
||||
if(rc == JNI_EVERSION)
|
||||
{
|
||||
errorString = "JVM is oudated and doesn't meet requirements";
|
||||
}
|
||||
else if(rc == JNI_ENOMEM)
|
||||
{
|
||||
errorString = "not enough memory for JVM";
|
||||
}
|
||||
else if(rc == JNI_EINVAL)
|
||||
{
|
||||
errorString = "invalid argument for launching JVM";
|
||||
}
|
||||
else if(rc == JNI_EEXIST)
|
||||
{
|
||||
errorString = "the process can only launch one JVM an not more";
|
||||
}
|
||||
else
|
||||
{
|
||||
errorString = "could not create the JVM instance (error code " + std::to_string(rc) + ")";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
jvm->DetachCurrentThread();
|
||||
s_instance = std::shared_ptr<JavaEnvironmentFactory>(new JavaEnvironmentFactory(jvm));
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<JavaEnvironmentFactory> JavaEnvironmentFactory::getInstance()
|
||||
{
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
JavaEnvironmentFactory::~JavaEnvironmentFactory()
|
||||
{
|
||||
// todo: what if there are threads running using the jvm?? log something!
|
||||
m_jvm->DestroyJavaVM();
|
||||
}
|
||||
|
||||
std::shared_ptr<JavaEnvironment> JavaEnvironmentFactory::createEnvironment()
|
||||
{
|
||||
std::thread::id currentThreadId = std::this_thread::get_id();
|
||||
|
||||
JNIEnv* env;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_threadIdToEnvAndUserCountMutex);
|
||||
|
||||
std::map<std::thread::id, std::pair<JNIEnv*, int>>::const_iterator it = m_threadIdToEnvAndUserCount.find(currentThreadId);
|
||||
if (it != m_threadIdToEnvAndUserCount.end())
|
||||
{
|
||||
env = it->second.first;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_jvm->AttachCurrentThread((void**)&env, NULL);
|
||||
m_threadIdToEnvAndUserCount.insert(std::make_pair(currentThreadId, std::make_pair(env, 0)));
|
||||
}
|
||||
}
|
||||
|
||||
return std::shared_ptr<JavaEnvironment>(new JavaEnvironment(m_jvm, env));
|
||||
}
|
||||
|
||||
std::shared_ptr<JavaEnvironmentFactory> JavaEnvironmentFactory::s_instance;
|
||||
|
||||
std::string JavaEnvironmentFactory::s_classPath;
|
||||
|
||||
JavaEnvironmentFactory::JavaEnvironmentFactory(JavaVM* jvm)
|
||||
: m_jvm(jvm)
|
||||
{
|
||||
}
|
||||
|
||||
void JavaEnvironmentFactory::registerEnvironment()
|
||||
{
|
||||
std::thread::id currentThreadId = std::this_thread::get_id();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_threadIdToEnvAndUserCountMutex);
|
||||
std::map<std::thread::id, std::pair<JNIEnv*, int>>::iterator it = m_threadIdToEnvAndUserCount.find(currentThreadId);
|
||||
if (it != m_threadIdToEnvAndUserCount.end())
|
||||
{
|
||||
it->second.second++;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("something went horribly wrong while registering a java environment");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JavaEnvironmentFactory::unregisterEnvironment()
|
||||
{
|
||||
std::thread::id currentThreadId = std::this_thread::get_id();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_threadIdToEnvAndUserCountMutex);
|
||||
std::map<std::thread::id, std::pair<JNIEnv*, int>>::iterator it = m_threadIdToEnvAndUserCount.find(currentThreadId);
|
||||
if (it != m_threadIdToEnvAndUserCount.end())
|
||||
{
|
||||
it->second.second--;
|
||||
if (it->second.second == 0)
|
||||
{ // TODO: currently this happens quite often. do something about that.
|
||||
m_jvm->DetachCurrentThread();
|
||||
m_threadIdToEnvAndUserCount.erase(it);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("something went horribly wrong while unregistering a java environment");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
#ifndef JAVA_ENVIRONMENT_FACTORY_H
|
||||
#define JAVA_ENVIRONMENT_FACTORY_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
struct JavaVM_;
|
||||
typedef JavaVM_ JavaVM;
|
||||
|
||||
struct JNIEnv_;
|
||||
typedef JNIEnv_ JNIEnv;
|
||||
|
||||
class JavaEnvironment;
|
||||
|
||||
class JavaEnvironmentFactory
|
||||
{
|
||||
public:
|
||||
static void createInstance(std::string classPath, std::string& errorString);
|
||||
static std::shared_ptr<JavaEnvironmentFactory> getInstance();
|
||||
|
||||
~JavaEnvironmentFactory();
|
||||
|
||||
std::shared_ptr<JavaEnvironment> createEnvironment();
|
||||
|
||||
private:
|
||||
friend class JavaEnvironment;
|
||||
|
||||
static std::shared_ptr<JavaEnvironmentFactory> s_instance;
|
||||
static std::string s_classPath;
|
||||
|
||||
JavaEnvironmentFactory(JavaVM* jvm);
|
||||
|
||||
void registerEnvironment();
|
||||
void unregisterEnvironment();
|
||||
|
||||
JavaVM* m_jvm;
|
||||
std::map<std::thread::id, std::pair<JNIEnv*, int>> m_threadIdToEnvAndUserCount;
|
||||
std::mutex m_threadIdToEnvAndUserCountMutex;
|
||||
};
|
||||
|
||||
#endif // JAVA_ENVIRONMENT_FACTORY_H
|
||||
@@ -1,43 +0,0 @@
|
||||
#ifndef TASK_PARSE_JAVA_H
|
||||
#define TASK_PARSE_JAVA_H
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "data/parser/Parser.h"
|
||||
#include "utility/scheduling/Task.h"
|
||||
#include "utility/messaging/type/MessageInterruptTasks.h"
|
||||
#include "utility/messaging/MessageListener.h"
|
||||
|
||||
class DialogView;
|
||||
class FileRegister;
|
||||
class StorageProvider;
|
||||
|
||||
class TaskParseJava
|
||||
: public Task
|
||||
, public MessageListener<MessageInterruptTasks>
|
||||
{
|
||||
public:
|
||||
TaskParseJava(
|
||||
std::shared_ptr<StorageProvider> storageProvider,
|
||||
std::shared_ptr<FileRegister> fileRegister,
|
||||
const Parser::Arguments& arguments,
|
||||
DialogView* dialogView
|
||||
);
|
||||
|
||||
private:
|
||||
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
|
||||
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
|
||||
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
|
||||
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
|
||||
|
||||
virtual void handleMessage(MessageInterruptTasks* message);
|
||||
|
||||
std::shared_ptr<StorageProvider> m_storageProvider;
|
||||
std::shared_ptr<FileRegister> m_fileRegister;
|
||||
Parser::Arguments m_arguments;
|
||||
DialogView* m_dialogView;
|
||||
|
||||
bool m_interrupted;
|
||||
};
|
||||
|
||||
#endif // TASK_PARSE_JAVA_H
|
||||
@@ -1,31 +0,0 @@
|
||||
#ifndef UTILITY_COMPLIATION_DATABASE_H
|
||||
#define UTILITY_COMPLIATION_DATABASE_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "utility/file/FilePath.h"
|
||||
|
||||
namespace utility
|
||||
{
|
||||
class CompilationDatabase
|
||||
{
|
||||
public:
|
||||
CompilationDatabase(std::string filename);
|
||||
|
||||
std::vector<FilePath> getAllHeaderPaths();
|
||||
std::vector<FilePath> getHeaderPaths();
|
||||
std::vector<FilePath> getSystemHeaderPaths();
|
||||
std::vector<FilePath> getFrameworkHeaderPaths();
|
||||
|
||||
private:
|
||||
std::string m_filename;
|
||||
std::vector<FilePath> m_headers;
|
||||
std::vector<FilePath> m_systemHeaders;
|
||||
std::vector<FilePath> m_frameworkHeaders;
|
||||
|
||||
void getHeaders();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // UTILITY_COMPLIATION_DATABASE_H
|
||||
@@ -0,0 +1,192 @@
|
||||
#include "utility/commandline/CommandLineParser.h"
|
||||
|
||||
#include "boost/program_options.hpp"
|
||||
|
||||
#include "utility/ConfigManager.h"
|
||||
#include "utility/file/FileSystem.h"
|
||||
#include "utility/messaging/type/MessageDispatchWhenLicenseValid.h"
|
||||
#include "utility/messaging/type/MessageLoadProject.h"
|
||||
#include "utility/messaging/type/MessageStatus.h"
|
||||
#include "utility/text/TextAccess.h"
|
||||
#include "utility/utilityString.h"
|
||||
#include "License.h"
|
||||
#include "PublicKey.h"
|
||||
|
||||
namespace po = boost::program_options;
|
||||
|
||||
CommandLineParser::CommandLineParser(int argc, char** argv, const std::string& version)
|
||||
: m_force(false)
|
||||
, m_quit(false)
|
||||
, m_withLicense(false)
|
||||
, m_withoutGUI(false)
|
||||
{
|
||||
std::string projectfile;
|
||||
std::string projectfile_db;
|
||||
std::string licensefile;
|
||||
std::string licensetext;
|
||||
po::options_description desc("Coati");
|
||||
desc.add_options()
|
||||
("help,h", "Print this help message")
|
||||
("version,v", "Version of Coati")
|
||||
("project,p", "Load Coati with a Coatiprojectfile")
|
||||
;
|
||||
po::positional_options_description positionalOption;
|
||||
positionalOption.add("project-file", 1);
|
||||
|
||||
po::options_description hidden_desc("hidden commandlineflags");
|
||||
hidden_desc.add_options()
|
||||
("force,f", "Force coati to parse if database exists")
|
||||
("licenseFile,z", po::value<std::string>(&licensefile), "Enter license via Licensefile")
|
||||
("license,l", po::value<std::string>(&licensetext), "Enter licenes via commandline")
|
||||
("hidden", "Print this help message with hidden arguments")
|
||||
("database,d", "Start coati to parse a Coati projectfile to get a coatidatabase")
|
||||
("project-file", po::value<std::string>(&projectfile), "Coati project file");
|
||||
;
|
||||
po::options_description all("Allowed options");
|
||||
all.add(desc).add(hidden_desc);
|
||||
|
||||
po::variables_map vm;
|
||||
po::store(po::command_line_parser(argc,argv).options(all).positional(positionalOption).allow_unregistered().run(), vm);
|
||||
po::notify(vm);
|
||||
|
||||
if (vm.count("help"))
|
||||
{
|
||||
std::cout << desc << std::endl;
|
||||
m_quit = true;
|
||||
}
|
||||
|
||||
if (vm.count("hidden"))
|
||||
{
|
||||
std::cout << all << std::endl;
|
||||
m_quit = true;
|
||||
}
|
||||
|
||||
if (vm.count("force"))
|
||||
{
|
||||
m_force = true;
|
||||
}
|
||||
|
||||
if (vm.count("license"))
|
||||
{
|
||||
licensetext = utility::replace(licensetext, "\\n", "\n");
|
||||
processLicense(m_license.loadFromString(licensetext));
|
||||
}
|
||||
|
||||
if (vm.count("licenseFile"))
|
||||
{
|
||||
std::cout << "licensefile flag" << std::endl;
|
||||
if (FileSystem::exists(licensefile))
|
||||
{
|
||||
std::cout << "licensefile exists" << std::endl;
|
||||
processLicense(m_license.loadFromFile(licensefile));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << licensefile << " not found" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (vm.count("version"))
|
||||
{
|
||||
std::cout << "Coati Version " << version << std::endl;
|
||||
m_quit = true;
|
||||
}
|
||||
|
||||
if (vm.count("project-file"))
|
||||
{
|
||||
processProjectfile(projectfile);
|
||||
if (vm.count("database"))
|
||||
{
|
||||
m_withoutGUI = true;
|
||||
}
|
||||
}
|
||||
else if (vm.count("database") || vm.count("project") ) {
|
||||
std::cout << "A project file is needed for this option" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void CommandLineParser::processLicense(const bool isLoaded)
|
||||
{
|
||||
if (!isLoaded)
|
||||
{
|
||||
std::cout << "Could not load License" << std::endl;
|
||||
}
|
||||
m_license.loadPublicKeyFromString(PublicKey);
|
||||
if (!m_license.isValid())
|
||||
{
|
||||
std::cout << "License is not valid" << std::endl;
|
||||
}
|
||||
m_withLicense = true;
|
||||
m_withoutGUI = true;
|
||||
}
|
||||
|
||||
CommandLineParser::~CommandLineParser()
|
||||
{
|
||||
}
|
||||
|
||||
bool CommandLineParser::runWithoutGUI()
|
||||
{
|
||||
return m_withoutGUI;
|
||||
}
|
||||
|
||||
bool CommandLineParser::exitApplication()
|
||||
{
|
||||
return m_quit;
|
||||
}
|
||||
|
||||
bool CommandLineParser::startedWithLicense()
|
||||
{
|
||||
return m_withLicense;
|
||||
}
|
||||
|
||||
void CommandLineParser::processProjectfile(const std::string& file)
|
||||
{
|
||||
FilePath projectfile(file);
|
||||
bool isValidProjectfile = true;
|
||||
std::string errorstring = "Provided Projectfile is not valid:\n";
|
||||
std::string errorProjectfile = "\tProvided Projectfile('" + projectfile.fileName() + ") ";
|
||||
if (!projectfile.exists())
|
||||
{
|
||||
errorstring += errorProjectfile + " does not exist\n";
|
||||
isValidProjectfile = false;
|
||||
}
|
||||
|
||||
if (projectfile.extension() != ".coatiproject")
|
||||
{
|
||||
errorstring += errorProjectfile + " has a wrong fileending\n";
|
||||
isValidProjectfile = false;
|
||||
}
|
||||
|
||||
std::shared_ptr<ConfigManager> configManager = ConfigManager::createEmpty();
|
||||
if (!configManager->load(TextAccess::createFromFile(projectfile.str())))
|
||||
{
|
||||
errorstring += errorProjectfile + " could not be loaded\n";
|
||||
isValidProjectfile = false;
|
||||
}
|
||||
|
||||
if (isValidProjectfile)
|
||||
{
|
||||
m_projectFile = projectfile.absolute().str();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << errorstring << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void CommandLineParser::projectLoad()
|
||||
{
|
||||
FilePath path(m_projectFile); // todo: use filepath as datatype for m_projectFile
|
||||
if (path.exists() && path.extension() == ".coatiproject")
|
||||
{
|
||||
MessageDispatchWhenLicenseValid(
|
||||
std::make_shared<MessageLoadProject>(path.str(), m_force)
|
||||
).dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
License CommandLineParser::getLicense()
|
||||
{
|
||||
return m_license;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef COMMANDLINEPARSER_H
|
||||
#define COMMANDLINEPARSER_H
|
||||
|
||||
#include <string>
|
||||
#include "Application.h"
|
||||
#include "License.h"
|
||||
|
||||
class CommandLineParser
|
||||
{
|
||||
public:
|
||||
CommandLineParser(int argc, char** argv, const std::string& version);
|
||||
~CommandLineParser();
|
||||
|
||||
bool runWithoutGUI();
|
||||
bool exitApplication();
|
||||
void projectLoad();
|
||||
bool startedWithLicense();
|
||||
License getLicense();
|
||||
private:
|
||||
void processProjectfile(const std::string& file);
|
||||
void processLicense(const bool isLoaded);
|
||||
std::string m_projectFile;
|
||||
|
||||
bool m_force;
|
||||
bool m_quit;
|
||||
bool m_withLicense;
|
||||
bool m_withoutGUI;
|
||||
|
||||
License m_license;
|
||||
};
|
||||
|
||||
#endif //COMMANDLINEPARSER_H
|
||||
Reference in New Issue
Block a user