diff --git a/java_indexer/src/io/coati/JavaIndexer.java b/java_indexer/src/io/coati/JavaIndexer.java
index 0417badb..83168302 100644
--- a/java_indexer/src/io/coati/JavaIndexer.java
+++ b/java_indexer/src/io/coati/JavaIndexer.java
@@ -6,12 +6,12 @@ import java.io.StringReader;
import java.lang.String;
import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.PackageDeclaration;
import com.github.javaparser.JavaParser;
-import com.github.javaparser.ParseException;
import com.github.javaparser.ParseProblemException;
import com.github.javaparser.Problem;
-import com.github.javaparser.Token;
+import me.tomassetti.symbolsolver.javaparser.Navigator;
import me.tomassetti.symbolsolver.javaparsermodel.JavaParserFacade;
import me.tomassetti.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
import me.tomassetti.symbolsolver.resolution.typesolvers.JarTypeSolver;
@@ -91,17 +91,31 @@ public class JavaIndexer
}
JavaParserFacade.clearInstances();
-
- // String fileName = filePath.substring(filePath.lastIndexOf("/"), filePath.lastIndexOf(".java"));
-
- // System.gc();
- // HeapDumper.dumpHeap("D:/dump/" + fileName, false);
}
-
-
-
-
+ public static String getPackageName(String fileContent)
+ {
+ String packageName = "";
+ try
+ {
+ CompilationUnit cu = JavaParser.parse(new StringReader(fileContent), true);
+ PackageDeclaration pd = Navigator.findNodeOfGivenClass(cu, PackageDeclaration.class);
+ if (pd != null)
+ {
+ packageName = JavaparserDeclNameResolver.getQualifiedName(pd.getName()).toString();
+ }
+ }
+ catch (ParseProblemException e)
+ {
+ // do nothing
+ }
+ catch (IllegalArgumentException e)
+ {
+ // do nothing
+ }
+
+ return packageName;
+ }
static public void recordSymbol(
int address, String symbolName, SymbolType symbolType,
diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp
index 34e033ee..add299f0 100644
--- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp
+++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp
@@ -212,8 +212,7 @@ QtProjectWizzardContentPathsSourceJava::QtProjectWizzardContentPathsSourceJava(
{
setHelpString(
"Project Paths define the files and directories that will be indexed by Coati. Provide a directory to recursively "
- "add all contained files. To make sure that type names are resolved correctly, please add the root source directory "
- "of your project (the one where all your package names are relative to).
"
+ "add all contained files.
"
"
"
"If your project's source code resides in one location, but generated source files are kept at a different location, "
"you will also need to add that directory."
@@ -465,7 +464,7 @@ QtProjectWizzardContentPathsClassJava::QtProjectWizzardContentPathsClassJava(
setTitleString("Class Path");
setHelpString(
"Enter all the .jar files your project depends on. If your project depends on uncompiled java code that should "
- "not be indexed, please add the root directory of those .java files here."
+ "not be indexed, please add the root directory of those .java files here (the one where all the package names are relative to)."
);
}
diff --git a/src/lib_java/JavaProject.cpp b/src/lib_java/JavaProject.cpp
index bb8dc2f3..393b12a3 100644
--- a/src/lib_java/JavaProject.cpp
+++ b/src/lib_java/JavaProject.cpp
@@ -1,9 +1,14 @@
#include "JavaProject.h"
+#include "component/view/DialogView.h"
#include "data/parser/java/JavaEnvironmentFactory.h"
+#include "data/parser/java/JavaEnvironment.h"
#include "data/parser/java/TaskParseJava.h"
+#include "utility/file/FileRegister.h"
+#include "utility/text/TextAccess.h"
#include "utility/messaging/type/MessageStatus.h"
#include "utility/ResourcePaths.h"
+#include "utility/utilityString.h"
#include "Application.h"
#include "isTrial.h"
@@ -31,6 +36,8 @@ const std::shared_ptr JavaProject::getProjectSettings() const
bool JavaProject::prepareIndexing()
{
+ m_rootDirectories.reset();
+
std::string errorString;
if (!JavaEnvironmentFactory::getInstance() && !isTrial())
{
@@ -89,11 +96,18 @@ std::shared_ptr JavaProject::createIndexerTask(
}
}
- for (FilePath sourcePath: m_projectSettings->getAbsoluteSourcePaths())
+ if (!m_rootDirectories)
{
- if (sourcePath.extension().empty() && sourcePath.exists())
+ getDialogView()->showProgressDialog("Preparing Project", "Gathering Root\nDirectories");
+ fetchRootDirectories();
+ getDialogView()->hideProgressDialog();
+ }
+
+ for (FilePath rootDirectory: *(m_rootDirectories.get()))
+ {
+ if (rootDirectory.exists())
{
- arguments.javaClassPaths.push_back(sourcePath.str());
+ arguments.javaClassPaths.push_back(rootDirectory.str());
}
}
@@ -114,3 +128,49 @@ void JavaProject::updateFileManager(FileManager& fileManager)
fileManager.setPaths(sourcePaths, headerPaths, excludePaths, sourceExtensions);
}
+
+void JavaProject::fetchRootDirectories()
+{
+ m_rootDirectories = std::make_shared>();
+
+ FileManager fileManager;
+ fileManager.setPaths(
+ m_projectSettings->getAbsoluteSourcePaths(),
+ std::vector(),
+ m_projectSettings->getAbsoluteExcludePaths(),
+ m_projectSettings->getSourceExtensions()
+ );
+ fileManager.fetchFilePaths(std::vector());
+ std::shared_ptr javaEnvironment = JavaEnvironmentFactory::getInstance()->createEnvironment();
+ for (FilePath filePath: fileManager.getAddedFilePaths())
+ {
+ std::shared_ptr textAccess = TextAccess::createFromFile(filePath.str());
+
+ std::string packageName = "";
+ javaEnvironment->callStaticMethod("io/coati/JavaIndexer", "getPackageName", packageName, textAccess->getText());
+
+ if (packageName.empty())
+ {
+ continue;
+ }
+
+ FilePath rootPath = filePath.parentDirectory();
+ bool success = true;
+
+ const std::vector packageNameParts = utility::splitToVector(packageName, ".");
+ for (std::vector::const_reverse_iterator it = packageNameParts.rbegin(); it != packageNameParts.rend(); it++)
+ {
+ if (rootPath.fileName() != (*it))
+ {
+ success = false;
+ break;
+ }
+ rootPath = rootPath.parentDirectory();
+ }
+
+ if (success)
+ {
+ m_rootDirectories->insert(rootPath);
+ }
+ }
+}
diff --git a/src/lib_java/JavaProject.h b/src/lib_java/JavaProject.h
index afda2840..14fb33e1 100644
--- a/src/lib_java/JavaProject.h
+++ b/src/lib_java/JavaProject.h
@@ -30,8 +30,11 @@ private:
std::shared_ptr fileRegister);
virtual void updateFileManager(FileManager& fileManager);
+
+ void fetchRootDirectories();
std::shared_ptr m_projectSettings;
+ std::shared_ptr> m_rootDirectories;
friend Project;
};
diff --git a/src/lib_java/data/parser/java/JavaEnvironment.cpp b/src/lib_java/data/parser/java/JavaEnvironment.cpp
index a648531c..b8ae68aa 100644
--- a/src/lib_java/data/parser/java/JavaEnvironment.cpp
+++ b/src/lib_java/data/parser/java/JavaEnvironment.cpp
@@ -12,31 +12,33 @@ JavaEnvironment::~JavaEnvironment()
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)
+ jclass javaClass = getJavaClass(className);
+ jmethodID javaMethodId = getJavaStaticMethod(javaClass, methodName, "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ if(javaMethodId != nullptr)
{
- LOG_ERROR("class " + className + " not found in JVM environment");
- jthrowable exc = m_env->ExceptionOccurred();
- if(exc)
- {
- m_env->ExceptionDescribe();
- m_env->ExceptionClear();
- }
+ 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;
}
- else
+ return false;
+}
+
+bool JavaEnvironment::callStaticMethod(std::string className, std::string methodName, std::string& ret, std::string arg1)
+{
+ jclass javaClass = getJavaClass(className);
+ jmethodID javaMethodId = getJavaStaticMethod(javaClass, methodName, "(Ljava/lang/String;)Ljava/lang/String;");
+ if(javaMethodId != nullptr)
{
- jmethodID javaMethodId = m_env->GetStaticMethodID(javaClass, methodName.c_str(), "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
- if(javaMethodId == nullptr)
+ jstring jarg1 = m_env->NewStringUTF(arg1.c_str());
+ jstring jret = (jstring)m_env->CallStaticObjectMethod(javaClass, javaMethodId, jarg1);
+ if (jret)
{
- 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);
+ const char *buffer = m_env->GetStringUTFChars(jret, JNI_FALSE);
+ ret = std::string(buffer);
+ m_env->ReleaseStringUTFChars(jret, buffer);
return true;
}
}
@@ -56,13 +58,6 @@ 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 methods)
{
JNINativeMethod* jniMethods = new JNINativeMethod[methods.size()];
@@ -90,3 +85,44 @@ void JavaEnvironment::registerNativeMethods(std::string className, std::vectorregisterEnvironment();
+}
+
+jclass JavaEnvironment::getJavaClass(const std::string& className)
+{
+ 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();
+ }
+ }
+ return javaClass;
+}
+
+jmethodID JavaEnvironment::getJavaStaticMethod(const std::string& className, const std::string& methodName, const std::string& methodSignature)
+{
+ return getJavaStaticMethod(getJavaClass(className), methodName, methodSignature);
+}
+
+jmethodID JavaEnvironment::getJavaStaticMethod(jclass javaClass, const std::string& methodName, const std::string& methodSignature)
+{
+ if(javaClass != nullptr)
+ {
+ jmethodID javaMethodId = m_env->GetStaticMethodID(javaClass, methodName.c_str(), methodSignature.c_str());
+ if(javaMethodId == nullptr)
+ {
+ LOG_ERROR("method " + methodName + methodSignature + " not found in JVM environment");
+ }
+ return javaMethodId;
+ }
+ return nullptr;
+}
diff --git a/src/lib_java/data/parser/java/JavaEnvironment.h b/src/lib_java/data/parser/java/JavaEnvironment.h
index 4613073f..0e41c26c 100644
--- a/src/lib_java/data/parser/java/JavaEnvironment.h
+++ b/src/lib_java/data/parser/java/JavaEnvironment.h
@@ -10,9 +10,15 @@ typedef JavaVM_ JavaVM;
struct JNIEnv_;
typedef JNIEnv_ JNIEnv;
+class _jclass;
+typedef _jclass *jclass;
+
class _jstring;
typedef _jstring *jstring;
+struct _jmethodID;
+typedef struct _jmethodID *jmethodID;
+
class JavaEnvironmentFactory;
class JavaEnvironment
@@ -27,6 +33,7 @@ public:
~JavaEnvironment();
bool callStaticVoidMethod(std::string className, std::string methodName, int arg1, std::string arg2, std::string arg3, std::string arg4);
+ bool callStaticMethod(std::string className, std::string methodName, std::string& ret, std::string arg1);
std::string toStdString(jstring s);
jstring toJString(std::string s);
@@ -36,6 +43,9 @@ private:
friend class JavaEnvironmentFactory;
JavaEnvironment(JavaVM* jvm, JNIEnv* env);
+ jclass getJavaClass(const std::string& className);
+ jmethodID getJavaStaticMethod(const std::string& className, const std::string& methodName, const std::string& methodSignature);
+ jmethodID getJavaStaticMethod(jclass javaClass, const std::string& methodName, const std::string& methodSignature);
JavaVM* m_jvm;
JNIEnv* m_env;