diff --git a/exaudfclient/base/javacontainer/javacontainer.cc b/exaudfclient/base/javacontainer/javacontainer.cc index f8de356c..71795bcd 100644 --- a/exaudfclient/base/javacontainer/javacontainer.cc +++ b/exaudfclient/base/javacontainer/javacontainer.cc @@ -1,13 +1,13 @@ #include "base/javacontainer/javacontainer.h" #include "base/javacontainer/javacontainer_impl.h" -#include "base/javacontainer/script_options/parser.h" +#include "base/javacontainer/script_options/extractor.h" using namespace SWIGVMContainers; using namespace std; -JavaVMach::JavaVMach(bool checkOnly, std::unique_ptr scriptOptionsParser) { +JavaVMach::JavaVMach(bool checkOnly,std::unique_ptr extractor) { try { - m_impl = new JavaVMImpl(checkOnly, false, std::move(scriptOptionsParser)); + m_impl = new JavaVMImpl(checkOnly, false, std::move(extractor)); } catch (std::exception& err) { lock_guard lock(exception_msg_mtx); exception_msg = "F-UDF-CL-SL-JAVA-1000: "+std::string(err.what()); diff --git a/exaudfclient/base/javacontainer/javacontainer.h b/exaudfclient/base/javacontainer/javacontainer.h index c8c1b91f..60bf69eb 100644 --- a/exaudfclient/base/javacontainer/javacontainer.h +++ b/exaudfclient/base/javacontainer/javacontainer.h @@ -14,7 +14,7 @@ class JavaVMImpl; namespace JavaScriptOptions { -struct ScriptOptionsParser; +struct Extractor; } @@ -23,7 +23,7 @@ class JavaVMach: public SWIGVM { /* * scriptOptionsParser: JavaVMach takes ownership of ScriptOptionsParser pointer. */ - JavaVMach(bool checkOnly, std::unique_ptr scriptOptionsParser); + JavaVMach(bool checkOnly, std::unique_ptr extractor); virtual ~JavaVMach() {} virtual void shutdown(); virtual bool run(); diff --git a/exaudfclient/base/javacontainer/javacontainer_builder.cc b/exaudfclient/base/javacontainer/javacontainer_builder.cc index 5eef3ef9..a08d787b 100644 --- a/exaudfclient/base/javacontainer/javacontainer_builder.cc +++ b/exaudfclient/base/javacontainer/javacontainer_builder.cc @@ -1,6 +1,5 @@ #include "base/javacontainer/javacontainer_builder.h" -#include "base/javacontainer/script_options/parser_ctpg.h" -#include "base/javacontainer/script_options/parser_legacy.h" +#include "base/javacontainer/script_options/extractor_impl.h" #include "base/swig_factory/swig_factory_impl.h" #ifdef ENABLE_JAVA_VM @@ -16,13 +15,13 @@ JavaContainerBuilder& JavaContainerBuilder::useCtpgParser() { } JavaVMach* JavaContainerBuilder::build() { - std::unique_ptr parser; + std::unique_ptr extractor; if (m_useCtpgParser) { - parser = std::make_unique(std::make_unique()); + extractor = std::make_unique(std::make_unique()); } else { - parser = std::make_unique(std::make_unique()); + extractor = std::make_unique(std::make_unique()); } - return new JavaVMach(false, std::move(parser)); + return new JavaVMach(false, std::move(extractor)); } diff --git a/exaudfclient/base/javacontainer/javacontainer_impl.cc b/exaudfclient/base/javacontainer/javacontainer_impl.cc index 58c190e0..cf36a3a7 100644 --- a/exaudfclient/base/javacontainer/javacontainer_impl.cc +++ b/exaudfclient/base/javacontainer/javacontainer_impl.cc @@ -12,14 +12,13 @@ #include "base/javacontainer/javacontainer.h" #include "base/javacontainer/javacontainer_impl.h" #include "base/javacontainer/script_options/extractor.h" -#include "base/javacontainer/script_options/parser.h" using namespace SWIGVMContainers; using namespace std; JavaVMImpl::JavaVMImpl(bool checkOnly, bool noJNI, - std::unique_ptr scriptOptionsParser) + std::unique_ptr extractor) : m_checkOnly(checkOnly) , m_exaJavaPath("") , m_localClasspath("/tmp") // **IMPORTANT**: /tmp needs to be in the classpath, otherwise ExaCompiler crashe with com.exasol.ExaCompilationException: /DATE_STRING.java:3: error: error while writing DATE_STRING: could not create parent directories @@ -32,7 +31,7 @@ JavaVMImpl::JavaVMImpl(bool checkOnly, bool noJNI, stringstream ss; m_exaJavaPath = "/exaudf/base/javacontainer"; // TODO hardcoded path - parseScriptOptions(std::move(scriptOptionsParser)); + parseScriptOptions(std::move(extractor)); m_needsCompilation = checkNeedsCompilation(); if (m_needsCompilation) { @@ -49,19 +48,14 @@ JavaVMImpl::JavaVMImpl(bool checkOnly, bool noJNI, } } -void JavaVMImpl::parseScriptOptions(std::unique_ptr scriptOptionsParser) { - JavaScriptOptions::Extractor extractor(*scriptOptionsParser); +void JavaVMImpl::parseScriptOptions(std::unique_ptr extractor) { - DBG_FUNC_CALL(cerr,extractor.extract(m_scriptCode)); + DBG_FUNC_CALL(cerr,extractor->extract(m_scriptCode)); DBG_FUNC_CALL(cerr,setClasspath()); - m_jvmOptions = std::move(extractor.moveJvmOptions()); - - for (set::iterator it = extractor.getJarPaths().begin(); it != extractor.getJarPaths().end(); - ++it) { - addJarToClasspath(*it); - } + m_jvmOptions = std::move(extractor->moveJvmOptions()); + extractor->iterateJarPaths([&](const std::string& s) { addJarToClasspath(s);}); } void JavaVMImpl::shutdown() { diff --git a/exaudfclient/base/javacontainer/javacontainer_impl.h b/exaudfclient/base/javacontainer/javacontainer_impl.h index 48bd413c..bf060eeb 100644 --- a/exaudfclient/base/javacontainer/javacontainer_impl.h +++ b/exaudfclient/base/javacontainer/javacontainer_impl.h @@ -16,7 +16,7 @@ class JavaVMTest; namespace SWIGVMContainers { namespace JavaScriptOptions { - struct ScriptOptionsParser; + struct Extractor; } class JavaVMImpl { @@ -25,8 +25,7 @@ class JavaVMImpl { /* * scriptOptionsParser: JavaVMImpl takes ownership of ScriptOptionsParser pointer. */ - JavaVMImpl(bool checkOnly, bool noJNI, - std::unique_ptr scriptOptionsParser); + JavaVMImpl(bool checkOnly, bool noJNI, std::unique_ptr extractor); ~JavaVMImpl() {} void shutdown(); bool run(); @@ -43,7 +42,7 @@ class JavaVMImpl { void setClasspath(); void setJvmOptions(); void addJarToClasspath(const std::string& path); - void parseScriptOptions(std::unique_ptr scriptOptionsParser); + void parseScriptOptions(std::unique_ptr extractor); bool m_checkOnly; std::string m_exaJavaPath; std::string m_localClasspath; diff --git a/exaudfclient/base/javacontainer/script_options/BUILD b/exaudfclient/base/javacontainer/script_options/BUILD index 1359a4fe..d0fae28d 100644 --- a/exaudfclient/base/javacontainer/script_options/BUILD +++ b/exaudfclient/base/javacontainer/script_options/BUILD @@ -3,8 +3,11 @@ package(default_visibility = ["//visibility:public"]) cc_library( name = "java_script_option_lines", - hdrs = [":extractor.h", ":parser_legacy.h", ":parser_ctpg.h"], - srcs = [":parser.h", ":converter.h", ":converter.cc", ":parser_legacy.cc", ":extractor.cc", + hdrs = [":extractor.h", ":extractor_impl.h", ":parser_legacy.h", ":parser_ctpg.h", + ":converter_v2.h", ":converter_legacy.h"], + srcs = [":parser.h", ":converter.h", ":converter.cc", ":parser_legacy.cc", ":extractor_impl.h", + ":extractor_impl.cc", ":converter_legacy.cc", ":converter_legacy.h", + ":converter_v2.cc", ":converter_v2.h", ":keywords.h", ":keywords.cc", ":checksum.h", ":checksum.cc", ":parser_ctpg.cc", ":parser_ctpg_script_importer.cc", ":parser_ctpg_script_importer.h", ":string_ops.h", ":string_ops.cc"], deps = ["@ssl//:ssl", "//base/script_options_parser/legacy:script_option_lines_parser_legacy", diff --git a/exaudfclient/base/javacontainer/script_options/converter.cc b/exaudfclient/base/javacontainer/script_options/converter.cc index 1c194e4a..1f641866 100644 --- a/exaudfclient/base/javacontainer/script_options/converter.cc +++ b/exaudfclient/base/javacontainer/script_options/converter.cc @@ -7,26 +7,8 @@ namespace SWIGVMContainers { namespace JavaScriptOptions { Converter::Converter() -: m_jvmOptions() -, m_jarPaths() -, m_whitespace(" \t\f\v") {} - -void Converter::convertExternalJar(const std::string & value) { - for (size_t start = 0, delim = 0; ; start = delim + 1) { - delim = value.find(":", start); - if (delim != std::string::npos) { - std::string jar = value.substr(start, delim - start); - if (m_jarPaths.find(jar) == m_jarPaths.end()) - m_jarPaths.insert(jar); - } - else { - std::string jar = value.substr(start); - if (m_jarPaths.find(jar) == m_jarPaths.end()) - m_jarPaths.insert(jar); - break; - } - } -} +: m_whitespace(" \t\f\v") +, m_jvmOptions() {} void Converter::convertScriptClassName(const std::string & value) { std::string trimmedValue(value); diff --git a/exaudfclient/base/javacontainer/script_options/converter.h b/exaudfclient/base/javacontainer/script_options/converter.h index 53a07029..07b53563 100644 --- a/exaudfclient/base/javacontainer/script_options/converter.h +++ b/exaudfclient/base/javacontainer/script_options/converter.h @@ -3,12 +3,8 @@ #include #include -#include -#include - -#include "base/javacontainer/script_options/parser.h" - - +#include +#include namespace SWIGVMContainers { @@ -19,32 +15,28 @@ class Converter { public: Converter(); - void convertExternalJar(const std::string & value); + virtual void convertExternalJar(const std::string & value) = 0; void convertScriptClassName(const std::string & value); void convertJvmOption(const std::string & value); - const std::set & getJarPaths() const { - return m_jarPaths; - } + virtual void iterateJarPaths(std::function callback) const = 0; std::vector&& moveJvmOptions() { return std::move(m_jvmOptions); } - private: + protected: + const std::string m_whitespace; + private: std::vector m_jvmOptions; - - std::set m_jarPaths; - const std::string m_whitespace; }; - } //namespace JavaScriptOptions } //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/converter_legacy.cc b/exaudfclient/base/javacontainer/script_options/converter_legacy.cc new file mode 100644 index 00000000..80621656 --- /dev/null +++ b/exaudfclient/base/javacontainer/script_options/converter_legacy.cc @@ -0,0 +1,33 @@ +#include "base/javacontainer/script_options/converter_legacy.h" +#include "base/javacontainer/script_options/string_ops.h" +#include + +namespace SWIGVMContainers { + +namespace JavaScriptOptions { + +ConverterLegacy::ConverterLegacy() +: Converter() +, m_jarPaths() {} + +void ConverterLegacy::convertExternalJar(const std::string & value) { + for (size_t start = 0, delim = 0; ; start = delim + 1) { + delim = value.find(":", start); + if (delim != std::string::npos) { + std::string jar = value.substr(start, delim - start); + if (m_jarPaths.find(jar) == m_jarPaths.end()) + m_jarPaths.insert(jar); + } + else { + std::string jar = value.substr(start); + if (m_jarPaths.find(jar) == m_jarPaths.end()) + m_jarPaths.insert(jar); + break; + } + } +} + + +} //namespace JavaScriptOptions + +} //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/converter_legacy.h b/exaudfclient/base/javacontainer/script_options/converter_legacy.h new file mode 100644 index 00000000..a3401c36 --- /dev/null +++ b/exaudfclient/base/javacontainer/script_options/converter_legacy.h @@ -0,0 +1,43 @@ +#ifndef SCRIPTOPTIONLINEPARSERCONVERTERLEGACY_H +#define SCRIPTOPTIONLINEPARSERCONVERTERLEGACY_H 1 + +#include +#include +#include +#include + +#include "base/javacontainer/script_options/converter.h" + + + +namespace SWIGVMContainers { + +namespace JavaScriptOptions { + +class ConverterLegacy : public Converter { + + public: + ConverterLegacy(); + + void convertExternalJar(const std::string & value); + + void iterateJarPaths(std::function callback) const override { + for (const auto & jar: m_jarPaths) { + callback(jar); + } + } + + private: + + std::set m_jarPaths; + +}; + + + + +} //namespace JavaScriptOptions + +} //namespace SWIGVMContainers + +#endif //SCRIPTOPTIONLINEPARSERCONVERTER_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/script_options/converter_v2.cc b/exaudfclient/base/javacontainer/script_options/converter_v2.cc new file mode 100644 index 00000000..4a94da62 --- /dev/null +++ b/exaudfclient/base/javacontainer/script_options/converter_v2.cc @@ -0,0 +1,35 @@ +#include "base/javacontainer/script_options/converter_v2.h" +#include "base/javacontainer/script_options/string_ops.h" +#include + +namespace SWIGVMContainers { + +namespace JavaScriptOptions { + +ConverterV2::ConverterV2() +: Converter() +, m_jarPaths() {} + +void ConverterV2::convertExternalJar(const std::string & value) { + std::string unquotedValue(value); + StringOps::removeQuotesSafely(unquotedValue, m_whitespace); + for (size_t start = 0, delim = 0; ; start = delim + 1) { + delim = unquotedValue.find(":", start); + if (delim != std::string::npos) { + std::string jar = unquotedValue.substr(start, delim - start); + StringOps::removeQuotesSafely(jar, m_whitespace); + m_jarPaths.push_back(jar); + } + else { + std::string jar = unquotedValue.substr(start); + StringOps::removeQuotesSafely(jar, m_whitespace); + m_jarPaths.push_back(jar); + break; + } + } +} + + +} //namespace JavaScriptOptions + +} //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/converter_v2.h b/exaudfclient/base/javacontainer/script_options/converter_v2.h new file mode 100644 index 00000000..1244a59e --- /dev/null +++ b/exaudfclient/base/javacontainer/script_options/converter_v2.h @@ -0,0 +1,43 @@ +#ifndef SCRIPTOPTIONLINEPARSERCONVERTERV2_H +#define SCRIPTOPTIONLINEPARSERCONVERTERV2_H 1 + +#include +#include +#include +#include + +#include "base/javacontainer/script_options/converter.h" + + + +namespace SWIGVMContainers { + +namespace JavaScriptOptions { + +class ConverterV2 : public Converter { + + public: + ConverterV2(); + + void convertExternalJar(const std::string & value); + + void iterateJarPaths(std::function callback) const override { + for (const auto & jar : m_jarPaths) { + callback(jar); + } + } + + private: + + std::vector m_jarPaths; + +}; + + + + +} //namespace JavaScriptOptions + +} //namespace SWIGVMContainers + +#endif //SCRIPTOPTIONLINEPARSERCONVERTER_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/script_options/extractor.h b/exaudfclient/base/javacontainer/script_options/extractor.h index 03ce623b..45546ad0 100644 --- a/exaudfclient/base/javacontainer/script_options/extractor.h +++ b/exaudfclient/base/javacontainer/script_options/extractor.h @@ -3,39 +3,23 @@ #include #include -#include +#include -#include "base/javacontainer/script_options/converter.h" - namespace SWIGVMContainers { namespace JavaScriptOptions { -class ScriptOptionsParser; - -class Extractor { - - public: - Extractor(ScriptOptionsParser & parser); +struct Extractor { + virtual ~Extractor() {} - const std::set & getJarPaths() const { - return m_converter.getJarPaths(); - } + virtual void iterateJarPaths(std::function callback) const = 0; - std::vector&& moveJvmOptions() { - return std::move(m_converter.moveJvmOptions()); - } + virtual std::vector&& moveJvmOptions() = 0; - void extract(std::string & scriptCode); - - private: - - Converter m_converter; - ScriptOptionsParser & m_parser; + virtual void extract(std::string & scriptCode) = 0; }; - } //namespace JavaScriptOptions } //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/extractor.cc b/exaudfclient/base/javacontainer/script_options/extractor_impl.cc similarity index 50% rename from exaudfclient/base/javacontainer/script_options/extractor.cc rename to exaudfclient/base/javacontainer/script_options/extractor_impl.cc index 9a75c1c1..9c6496a2 100644 --- a/exaudfclient/base/javacontainer/script_options/extractor.cc +++ b/exaudfclient/base/javacontainer/script_options/extractor_impl.cc @@ -1,6 +1,4 @@ -#include "base/javacontainer/script_options/extractor.h" -#include "base/javacontainer/script_options/parser.h" - +#include "base/javacontainer/script_options/extractor_impl.h" #include "base/utils/debug_message.h" #include @@ -10,10 +8,23 @@ namespace SWIGVMContainers { namespace JavaScriptOptions { -Extractor::Extractor(ScriptOptionsParser & parser) -: m_parser(parser) {} +template +ExtractorImpl::ExtractorImpl(std::unique_ptr swigFactory) +: m_parser(std::move(swigFactory)) +, m_converter() {} + +template +inline void ExtractorImpl::iterateJarPaths(std::function callback) const { + m_converter.iterateJarPaths(callback); +} + +template +inline std::vector&& ExtractorImpl::moveJvmOptions() { + return std::move(m_converter.moveJvmOptions()); +} -void Extractor::extract(std::string & scriptCode) { +template +void ExtractorImpl::extract(std::string & scriptCode) { m_parser.prepareScriptCode(scriptCode); EXTR_DBG_FUNC_CALL(m_parser.parseForScriptClass( [&](const std::string& value){ EXTR_DBG_FUNC_CALL(m_converter.convertScriptClassName(value)); // To be called before scripts are imported. Otherwise, the script classname from an imported script could be used @@ -22,12 +33,20 @@ void Extractor::extract(std::string & scriptCode) { EXTR_DBG_FUNC_CALL(m_parser.parseForJvmOptions( [&](const std::string& value){ EXTR_DBG_FUNC_CALL(m_converter.convertJvmOption(value)); })); + EXTR_DBG_FUNC_CALL(m_parser.parseForExternalJars( [&](const std::string& value){ EXTR_DBG_FUNC_CALL(m_converter.convertExternalJar(value)); })); + scriptCode = std::move(m_parser.getScriptCode()); } + +// Explict class template instantiations +template class ExtractorImpl; +template class ExtractorImpl; + + } //namespace JavaScriptOptions } //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/extractor_impl.h b/exaudfclient/base/javacontainer/script_options/extractor_impl.h new file mode 100644 index 00000000..e071958c --- /dev/null +++ b/exaudfclient/base/javacontainer/script_options/extractor_impl.h @@ -0,0 +1,44 @@ +#ifndef SCRIPTOPTIONLINEPEXTRACTORIMPL_H +#define SCRIPTOPTIONLINEPEXTRACTORIMPL_H 1 + +#include +#include +#include + + +#include "base/javacontainer/script_options/extractor.h" +#include "base/javacontainer/script_options/converter_legacy.h" +#include "base/javacontainer/script_options/converter_v2.h" +#include "base/javacontainer/script_options/parser_ctpg.h" +#include "base/javacontainer/script_options/parser_legacy.h" +#include "base/swig_factory/swig_factory.h" + +namespace SWIGVMContainers { + +namespace JavaScriptOptions { + +template +class ExtractorImpl : public Extractor { + + public: + + ExtractorImpl(std::unique_ptr swigFactory); + + void iterateJarPaths(std::function callback) const override; + std::vector&& moveJvmOptions() override; + + void extract(std::string & scriptCode); + + private: + TParser m_parser; + TConverter m_converter; +}; + +typedef ExtractorImpl tExtractorLegacy; +typedef ExtractorImpl tExtractorV2; + +} //namespace JavaScriptOptions + +} //namespace SWIGVMContainers + +#endif //SCRIPTOPTIONLINEPEXTRACTORIMPL_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/script_options/parser_ctpg.cc b/exaudfclient/base/javacontainer/script_options/parser_ctpg.cc index 3f576242..ba8e5ba9 100644 --- a/exaudfclient/base/javacontainer/script_options/parser_ctpg.cc +++ b/exaudfclient/base/javacontainer/script_options/parser_ctpg.cc @@ -3,6 +3,7 @@ #include "base/utils/exceptions.h" #include "base/script_options_parser/exception.h" #include "base/swig_factory/swig_factory.h" +#include "base/javacontainer/script_options/string_ops.h" #include diff --git a/exaudfclient/base/javacontainer/script_options/string_ops.cc b/exaudfclient/base/javacontainer/script_options/string_ops.cc index df1b6081..5a59743c 100644 --- a/exaudfclient/base/javacontainer/script_options/string_ops.cc +++ b/exaudfclient/base/javacontainer/script_options/string_ops.cc @@ -1 +1,42 @@ #include "base/javacontainer/script_options/string_ops.h" +#include + +namespace SWIGVMContainers { + +namespace JavaScriptOptions { + +namespace StringOps { + +void removeQuotesSafely(std::string & s, const std::string & whitespaces) { + const size_t startQuoteIdx = s.find_first_of("\"'"); + const size_t endQuoteIdx = s.find_last_of("\"'"); + + if (startQuoteIdx != std::string::npos && endQuoteIdx != std::string::npos && startQuoteIdx < endQuoteIdx && + s[startQuoteIdx] == s[endQuoteIdx]) { + //Search backwards if there any none whitespace characters in front of quote. If yes, we ignore the quote. + if (startQuoteIdx > 0) { + const size_t startingNotWhitespace = s.find_last_not_of(whitespaces, startQuoteIdx-1); + if (startingNotWhitespace != std::string::npos) { + return; + } + } + + //Search forward if there any none whitespace characters after ending quote. If yes, we ignore the quote. + if (endQuoteIdx < s.size() -1 ) { + const size_t trailingNotWhitespace = s.find_first_not_of(whitespaces, endQuoteIdx+1); + if (trailingNotWhitespace != std::string::npos) { + return; + } + } + s = s.substr(startQuoteIdx+1, endQuoteIdx-startQuoteIdx-1); + std::cerr << "DEBUG0 :" << startQuoteIdx << "-" << endQuoteIdx << std::endl; + std::cerr << "DEBUG1 :" << s << std::endl; + } +} + +} //namespace StringOps + + +} //namespace JavaScriptOptions + +} //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/string_ops.h b/exaudfclient/base/javacontainer/script_options/string_ops.h index 8e0ff72c..c382b545 100644 --- a/exaudfclient/base/javacontainer/script_options/string_ops.h +++ b/exaudfclient/base/javacontainer/script_options/string_ops.h @@ -31,6 +31,9 @@ inline void trim(std::string &s) { rtrim(s); } +void removeQuotesSafely(std::string & s, const std::string & whitespaces); + + } //namespace StringOps diff --git a/exaudfclient/base/javacontainer/script_options/test/BUILD b/exaudfclient/base/javacontainer/script_options/test/BUILD index c76203ab..c898c29c 100644 --- a/exaudfclient/base/javacontainer/script_options/test/BUILD +++ b/exaudfclient/base/javacontainer/script_options/test/BUILD @@ -1,10 +1,10 @@ cc_test( name = "java-script-options-tests", - srcs = ["ctpg_script_importer_test.cc", "swig_factory_test.cc", "swig_factory_test.h", "string_ops_tests.cc"], + srcs = ["ctpg_script_importer_test.cc", "swig_factory_test.cc", "swig_factory_test.h", + "string_ops_tests.cc", "converter_test.cc"], deps = [ "//base/javacontainer/script_options:java_script_option_lines", "@googletest//:gtest_main", ], ) - diff --git a/exaudfclient/base/javacontainer/script_options/test/converter_test.cc b/exaudfclient/base/javacontainer/script_options/test/converter_test.cc new file mode 100644 index 00000000..64b1c1df --- /dev/null +++ b/exaudfclient/base/javacontainer/script_options/test/converter_test.cc @@ -0,0 +1,69 @@ + +#include "include/gtest/gtest.h" +#include "gmock/gmock.h" +#include "base/javacontainer/script_options/converter_legacy.h" +#include "base/javacontainer/script_options/converter_v2.h" + +using namespace SWIGVMContainers::JavaScriptOptions; + + +class ConverterJarTest : public ::testing::TestWithParam>> {}; + +TEST_P(ConverterJarTest, jar) { + const std::pair> option_value = GetParam(); + const std::string jar_option_value = option_value.first; + + ConverterLegacy converter; + + converter.convertExternalJar(option_value.first); + + std::vector result; + converter.iterateJarPaths([&](auto jar) {result.push_back(jar);}); + ASSERT_EQ(result, option_value.second); +} + +const std::vector>> jar_strings = + { + std::make_pair("test.jar:test2.jar", std::vector({"test.jar", "test2.jar"})), + std::make_pair("\"test.jar:test2.jar\"", std::vector({"\"test.jar", "test2.jar\""})), + std::make_pair("t\\:est.jar:test2.jar", std::vector({"est.jar", "t\\", "test2.jar"})), + }; + +INSTANTIATE_TEST_SUITE_P( + Converter, + ConverterJarTest, + ::testing::ValuesIn(jar_strings) +); + + + +class ConverterV2JarTest : public ::testing::TestWithParam>> {}; + +TEST_P(ConverterV2JarTest, jar) { + const std::pair> option_value = GetParam(); + const std::string jar_option_value = option_value.first; + + ConverterV2 converter; + converter.convertExternalJar(option_value.first); + std::vector result; + converter.iterateJarPaths([&](auto jar) {result.push_back(jar);}); + ASSERT_EQ(result, option_value.second); +} + +const std::vector>> jar_strings_v2 = + { + std::make_pair("test.jar:test2.jar", std::vector({"test.jar", "test2.jar"})), + std::make_pair("\"test.jar:test2.jar\"", std::vector({"test.jar", "test2.jar"})), + std::make_pair("\"test .jar:test2.jar\"", std::vector({"test .jar", "test2.jar"})), + std::make_pair("\"test .jar\":test2.jar", std::vector({"test .jar", "test2.jar"})), + std::make_pair("'test .jar':test2.jar", std::vector({"test .jar", "test2.jar"})), + std::make_pair("\"test .jar':test2.jar", std::vector({"\"test .jar'", "test2.jar"})), + std::make_pair(" \"test .jar ' : ' test2.jar ' \t", std::vector({" \"test .jar ' ", " test2.jar "})), + std::make_pair(" abc \"test .jar ' : ' test2.jar ' \t", std::vector({" abc \"test .jar ' ", " test2.jar "})), + }; + +INSTANTIATE_TEST_SUITE_P( + Converter, + ConverterV2JarTest, + ::testing::ValuesIn(jar_strings_v2) +); diff --git a/exaudfclient/base/javacontainer/script_options/test/string_ops_tests.cc b/exaudfclient/base/javacontainer/script_options/test/string_ops_tests.cc index 8eaf722b..ec8a8e1f 100644 --- a/exaudfclient/base/javacontainer/script_options/test/string_ops_tests.cc +++ b/exaudfclient/base/javacontainer/script_options/test/string_ops_tests.cc @@ -25,3 +25,30 @@ TEST(StringOpsTest, trimWithNoneASCII) { EXPECT_EQ(sample, "\xa0Hello World\xa0"); } +class QuotedTest : public ::testing::TestWithParam> {}; + +TEST_P(QuotedTest, test) { + const std::pair quoted_strings = GetParam(); + std::string quoted_string = quoted_strings.first; + StringOps::removeQuotesSafely(quoted_string, " \t"); + EXPECT_EQ(quoted_string, quoted_strings.second); +} + +const std::vector> quoted_strings = + { + std::make_pair("string", "string"), + std::make_pair("\"string", "\"string"), + std::make_pair("\"string\"", "string"), + std::make_pair("\"string'", "\"string'"), + std::make_pair("'string'", "string"), + std::make_pair("' string '", " string "), + std::make_pair("' ' string '", " ' string "), + std::make_pair(" ' ' string '", " ' string "), + std::make_pair(" aaa ' ' string '", " aaa ' ' string '"), + }; + +INSTANTIATE_TEST_SUITE_P( + QuotedTest, + QuotedTest, + ::testing::ValuesIn(quoted_strings) +); diff --git a/exaudfclient/base/javacontainer/test/cpp/javacontainer_ctpg_test.cc b/exaudfclient/base/javacontainer/test/cpp/javacontainer_ctpg_test.cc index e66168e5..350e835e 100644 --- a/exaudfclient/base/javacontainer/test/cpp/javacontainer_ctpg_test.cc +++ b/exaudfclient/base/javacontainer/test/cpp/javacontainer_ctpg_test.cc @@ -3,11 +3,16 @@ #include "gmock/gmock.h" #include "base/javacontainer/test/cpp/javavm_test.h" #include "base/javacontainer/test/cpp/swig_factory_test.h" +#include "base/javacontainer/javacontainer.h" +#include "base/javacontainer/script_options/converter.h" #include #include +using ::testing::MatchesRegex; + class JavaContainerEscapeSequenceTest : public ::testing::TestWithParam> {}; + TEST_P(JavaContainerEscapeSequenceTest, quoted_jvm_option) { const std::pair option_value = GetParam(); const std::string script_code = @@ -107,3 +112,38 @@ TEST(JavaContainer, import_script_with_escaped_options) { "-XX:+UseSerialGC" }; EXPECT_EQ(vm.getJavaVMInternalStatus().m_jvmOptions, expectedJVMOptions); } + +TEST(JavaContainer, basic_jar_with_quoted_white_spaces) { + const std::string script_code = "%jar \"base/javacontainer/test/test.jar \t \";"; + + EXPECT_THROW({ + try + { + JavaVMTest vm(script_code); + } + catch( const SWIGVMContainers::JavaVMach::exception& e ) + { + EXPECT_THAT( e.what(), MatchesRegex("^.*Java VM cannot find 'base/javacontainer/test/test\\.jar \t ': No such file or directory$")); + throw; + } + }, SWIGVMContainers::JavaVMach::exception ); +} + + +TEST(JavaContainer, basic_jars_order_remains) { + const std::string script_code = "%jar \"base/javacontainer/test/test1.jar\":base/javacontainer/test/abc.jar;"; + + EXPECT_THROW({ + try + { + JavaVMTest vm(script_code); + } + catch( const SWIGVMContainers::JavaVMach::exception& e ) + { + EXPECT_THAT( e.what(), MatchesRegex("^.*Java VM cannot find 'base/javacontainer/test/test1\\.jar': No such file or directory$")); + throw; + } + }, SWIGVMContainers::JavaVMach::exception ); +} + + diff --git a/exaudfclient/base/javacontainer/test/cpp/javavm_test.cc b/exaudfclient/base/javacontainer/test/cpp/javavm_test.cc index 79dfdad7..fd2b89b1 100644 --- a/exaudfclient/base/javacontainer/test/cpp/javavm_test.cc +++ b/exaudfclient/base/javacontainer/test/cpp/javavm_test.cc @@ -1,8 +1,7 @@ #include "base/javacontainer/test/cpp/javavm_test.h" #include "base/javacontainer/test/cpp/swig_factory_test.h" #include "base/javacontainer/javacontainer_impl.h" -#include "base/javacontainer/script_options/parser_ctpg.h" -#include "base/javacontainer/script_options/parser_legacy.h" +#include "base/javacontainer/script_options/extractor_impl.h" #include std::unique_ptr makeDefaultSwigFactory() { @@ -20,13 +19,13 @@ JavaVMTest::JavaVMTest(std::string scriptCode, std::unique_ptr swigFactory) { SWIGVMContainers::SWIGVM_params->script_code = scriptCode.data(); #ifndef USE_CTPG_PARSER - std::unique_ptr parser = - std::make_unique(std::move(swigFactory)); + std::unique_ptr extractor = + std::make_unique(std::move(swigFactory)); #else - std::unique_ptr parser = - std::make_unique(std::move(swigFactory)); + std::unique_ptr extractor = + std::make_unique(std::move(swigFactory)); #endif - SWIGVMContainers::JavaVMImpl javaVMImpl(false, true, std::move(parser)); + SWIGVMContainers::JavaVMImpl javaVMImpl(false, true, std::move(extractor)); javaVMInternalStatus.m_exaJavaPath = javaVMImpl.m_exaJavaPath; javaVMInternalStatus.m_localClasspath = javaVMImpl.m_localClasspath; javaVMInternalStatus.m_scriptCode = javaVMImpl.m_scriptCode; diff --git a/exaudfclient/base/utils/debug_message.h b/exaudfclient/base/utils/debug_message.h index e74d892e..35aa2739 100644 --- a/exaudfclient/base/utils/debug_message.h +++ b/exaudfclient/base/utils/debug_message.h @@ -7,6 +7,7 @@ #define PRINT_ERROR_MESSAGE( os, error_code, error_message ) \ (os) << (error_code) << ":" << error_message << std::endl +#define NDEBUG 1 #ifndef NDEBUG #define DBG_EXCEPTION( os, ex ) \