diff --git a/exaudfclient/base/javacontainer/javacontainer.cc b/exaudfclient/base/javacontainer/javacontainer.cc index 797506cb..df571f02 100644 --- a/exaudfclient/base/javacontainer/javacontainer.cc +++ b/exaudfclient/base/javacontainer/javacontainer.cc @@ -4,9 +4,9 @@ using namespace SWIGVMContainers; using namespace std; -JavaVMach::JavaVMach(bool checkOnly, SwigFactory& swigFactory) { +JavaVMach::JavaVMach(bool checkOnly, SwigFactory& swigFactory, bool useCTPGParser) { try { - m_impl = new JavaVMImpl(checkOnly, false, swigFactory); + m_impl = new JavaVMImpl(checkOnly, false, swigFactory, useCTPGParser); } 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 dc7ba418..46fd0670 100644 --- a/exaudfclient/base/javacontainer/javacontainer.h +++ b/exaudfclient/base/javacontainer/javacontainer.h @@ -14,7 +14,7 @@ class SwigFactory; class JavaVMach: public SWIGVM { public: - JavaVMach(bool checkOnly, SwigFactory& swigFactory); + JavaVMach(bool checkOnly, SwigFactory& swigFactory, bool useCTPGParser); virtual ~JavaVMach() {} virtual void shutdown(); virtual bool run(); diff --git a/exaudfclient/base/javacontainer/javacontainer_impl.cc b/exaudfclient/base/javacontainer/javacontainer_impl.cc index 31d37d30..6f3845bc 100644 --- a/exaudfclient/base/javacontainer/javacontainer_impl.cc +++ b/exaudfclient/base/javacontainer/javacontainer_impl.cc @@ -13,13 +13,14 @@ #include "base/javacontainer/javacontainer_impl.h" #include "base/javacontainer/script_options/extractor.h" #include "base/javacontainer/script_options/parser_legacy.h" +#include "base/javacontainer/script_options/parser_ctpg.h" #include "base/swig_factory/swig_factory.h" using namespace SWIGVMContainers; using namespace std; -JavaVMImpl::JavaVMImpl(bool checkOnly, bool noJNI, SwigFactory& swigFactory) +JavaVMImpl::JavaVMImpl(bool checkOnly, bool noJNI, SwigFactory& swigFactory, bool useCTPGParser) : 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 @@ -34,19 +35,12 @@ JavaVMImpl::JavaVMImpl(bool checkOnly, bool noJNI, SwigFactory& swigFactory) stringstream ss; m_exaJavaPath = "/exaudf/base/javacontainer"; // TODO hardcoded path - JavaScriptOptions::ScriptOptionLinesParserLegacy scriptOptionsParser; - JavaScriptOptions::Extractor extractor(scriptOptionsParser, swigFactory, - [&](const std::string &msg){throwException(msg);}); - - DBG_FUNC_CALL(cerr,extractor.extract(m_scriptCode)); // To be called before scripts are imported. Otherwise, the script classname from an imported script could be used - - 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); + if (useCTPGParser) { + JavaScriptOptions::ScriptOptionLinesParserCTPG parser; + parseScriptOptions(parser, swigFactory); + } else { + JavaScriptOptions::ScriptOptionLinesParserLegacy parser; + parseScriptOptions(parser, swigFactory); } m_needsCompilation = checkNeedsCompilation(); @@ -64,6 +58,22 @@ JavaVMImpl::JavaVMImpl(bool checkOnly, bool noJNI, SwigFactory& swigFactory) } } +void JavaVMImpl::parseScriptOptions(JavaScriptOptions::ScriptOptionsParser & scriptOptionsParser, SwigFactory& swigFactory) { + JavaScriptOptions::Extractor extractor(scriptOptionsParser, swigFactory, + [&](const std::string &msg){throwException(msg);}); + + DBG_FUNC_CALL(cerr,extractor.extract(m_scriptCode)); // To be called before scripts are imported. Otherwise, the script classname from an imported script could be used + + 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); + } +} + void JavaVMImpl::shutdown() { if (m_checkOnly) throwException("F-UDF.CL.SL.JAVA-1159: Java VM in check only mode"); diff --git a/exaudfclient/base/javacontainer/javacontainer_impl.h b/exaudfclient/base/javacontainer/javacontainer_impl.h index f4f093be..d423f32f 100644 --- a/exaudfclient/base/javacontainer/javacontainer_impl.h +++ b/exaudfclient/base/javacontainer/javacontainer_impl.h @@ -14,10 +14,14 @@ class JavaVMTest; namespace SWIGVMContainers { +namespace JavaScriptOptions { + struct ScriptOptionsParser; +} + class JavaVMImpl { public: friend class ::JavaVMTest; - JavaVMImpl(bool checkOnly, bool noJNI, SwigFactory& swigFactory); + JavaVMImpl(bool checkOnly, bool noJNI, SwigFactory& swigFactory, bool useCTPGParser); ~JavaVMImpl() {} void shutdown(); bool run(); @@ -37,6 +41,7 @@ class JavaVMImpl { void throwException(const std::string& ex); void setJvmOptions(); void addJarToClasspath(const std::string& path); + void parseScriptOptions(JavaScriptOptions::ScriptOptionsParser & scriptOptionsParser, SwigFactory& swigFactory); 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 e453ec0b..c972d880 100644 --- a/exaudfclient/base/javacontainer/script_options/BUILD +++ b/exaudfclient/base/javacontainer/script_options/BUILD @@ -3,9 +3,11 @@ package(default_visibility = ["//visibility:public"]) cc_library( name = "java_script_option_lines", - hdrs = [":extractor.h", ":parser_legacy.h"], + hdrs = [":extractor.h", ":parser_legacy.h", ":parser_ctpg.h"], srcs = [":parser.h", ":converter.h", ":converter.cc", ":parser_legacy.cc", ":extractor.cc", - ":keywords.h", ":checksum.h", ":checksum.cc"], - deps = ["//base/script_options_parser/legacy:script_option_lines_parser_legacy", "//base:debug_message_h", + ":keywords.h", ":keywords.cc", ":checksum.h", ":checksum.cc", ":parser_ctpg.cc", + ":parser_ctpg_script_importer.cc", ":parser_ctpg_script_importer.h"], + deps = ["//base/script_options_parser/legacy:script_option_lines_parser_legacy", + "//base/script_options_parser/ctpg:script_option_lines_parser_ctpg", "//base:debug_message_h", "//base/exaudflib:header", "//base/exaudflib:exaudflib-deps", "//base/swig_factory:swig_factory_if"], ) diff --git a/exaudfclient/base/javacontainer/script_options/extractor.cc b/exaudfclient/base/javacontainer/script_options/extractor.cc index f14e1ef4..efe76675 100644 --- a/exaudfclient/base/javacontainer/script_options/extractor.cc +++ b/exaudfclient/base/javacontainer/script_options/extractor.cc @@ -29,7 +29,7 @@ void Extractor::extract(std::string & scriptCode) { EXTR_DBG_FUNC_CALL(m_parser.parseForExternalJars( [&](const std::string& value){ EXTR_DBG_FUNC_CALL(m_converter.convertExternalJar(value)); }, m_throwException)); - scriptCode = std::move(m_parser.getScriptCode()); + scriptCode = std::move(m_parser.getScriptCode(m_throwException)); } } //namespace JavaScriptOptions diff --git a/exaudfclient/base/javacontainer/script_options/keywords.cc b/exaudfclient/base/javacontainer/script_options/keywords.cc new file mode 100644 index 00000000..9d89bf38 --- /dev/null +++ b/exaudfclient/base/javacontainer/script_options/keywords.cc @@ -0,0 +1,33 @@ +#include "base/javacontainer/script_options/keywords.h" +#include + +namespace SWIGVMContainers { + +namespace JavaScriptOptions { + +Keywords::Keywords(bool withScriptOptionsPrefix) +: m_jarKeyword() +, m_scriptClassKeyword() +, m_importKeyword() +, m_jvmKeyword() { + const std::string_view jar{"%jar"}; + const std::string_view scriptClass{"%scriptclass"}; + const std::string_view import{"%import"}; + const std::string_view jvm{"%jvmoption"}; + if (withScriptOptionsPrefix) { + m_jarKeyword = jar; + m_scriptClassKeyword = scriptClass; + m_importKeyword = import; + m_jvmKeyword = jvm; + } else { + m_jarKeyword.assign(jar.substr(1)); + m_scriptClassKeyword.assign(scriptClass.substr(1)); + m_importKeyword.assign(import.substr(1)); + m_jvmKeyword.assign(jvm.substr(1)); + } +} + +} //namespace JavaScriptOptions + +} //namespace SWIGVMContainers + diff --git a/exaudfclient/base/javacontainer/script_options/keywords.h b/exaudfclient/base/javacontainer/script_options/keywords.h index 840509a9..314bf5b6 100644 --- a/exaudfclient/base/javacontainer/script_options/keywords.h +++ b/exaudfclient/base/javacontainer/script_options/keywords.h @@ -9,20 +9,16 @@ namespace JavaScriptOptions { class Keywords { public: - Keywords() - : m_jarKeyword("%jar") - , m_scriptClassKeyword("%scriptclass") - , m_importKeyword("%import") - , m_jvmOptionKeyword("%jvmoption") {} - const std::string & jarKeyword() { return m_jarKeyword; } + Keywords(bool withScriptOptionsPrefix); const std::string & scriptClassKeyword() { return m_scriptClassKeyword; } const std::string & importKeyword() { return m_importKeyword; } - const std::string & jvmOptionKeyword() { return m_jvmOptionKeyword; } + const std::string & jvmKeyword() { return m_jvmKeyword; } + const std::string & jarKeyword() { return m_jarKeyword; } private: std::string m_jarKeyword; std::string m_scriptClassKeyword; std::string m_importKeyword; - std::string m_jvmOptionKeyword; + std::string m_jvmKeyword; }; } //namespace JavaScriptOptions diff --git a/exaudfclient/base/javacontainer/script_options/parser.h b/exaudfclient/base/javacontainer/script_options/parser.h index 974e80a0..04978c76 100644 --- a/exaudfclient/base/javacontainer/script_options/parser.h +++ b/exaudfclient/base/javacontainer/script_options/parser.h @@ -51,7 +51,7 @@ struct ScriptOptionsParser { /* Returns the (eventually modified) script code. */ - virtual std::string && getScriptCode() = 0; + virtual std::string && getScriptCode(std::function throwException) = 0; }; } //namespace JavaScriptOptions diff --git a/exaudfclient/base/javacontainer/script_options/parser_ctpg.cc b/exaudfclient/base/javacontainer/script_options/parser_ctpg.cc index cd73abb7..7069a201 100644 --- a/exaudfclient/base/javacontainer/script_options/parser_ctpg.cc +++ b/exaudfclient/base/javacontainer/script_options/parser_ctpg.cc @@ -1,9 +1,128 @@ #include "base/javacontainer/script_options/parser_ctpg.h" +#include "base/javacontainer/script_options/parser_ctpg_script_importer.h" +#include + +namespace ctpg_parser = ExecutionGraph::OptionsLineParser::CTPG; namespace SWIGVMContainers { namespace JavaScriptOptions { +ScriptOptionLinesParserCTPG::ScriptOptionLinesParserCTPG() +: m_scriptCode() +, m_keywords(false) +, m_needParsing(true) {} + +void ScriptOptionLinesParserCTPG::prepareScriptCode(const std::string & scriptCode) { + m_scriptCode = scriptCode; +} + +void ScriptOptionLinesParserCTPG::parseForScriptClass(std::function callback, + std::function throwException) { + parseForSingleOption(m_keywords.scriptClassKeyword(), callback, + [&](const std::string& msg){throwException("F-UDF-CL-SL-JAVA-1623 " + msg);}); +} + +void ScriptOptionLinesParserCTPG::parseForJvmOptions(std::function callback, + std::function throwException) { + parseForMultipleOption(m_keywords.jvmKeyword(), callback, + [&](const std::string& msg){throwException("F-UDF-CL-SL-JAVA-1624 " + msg);}); +} + +void ScriptOptionLinesParserCTPG::parseForExternalJars(std::function callback, + std::function throwException) { + parseForMultipleOption(m_keywords.jarKeyword(), callback, + [&](const std::string& msg){throwException("F-UDF-CL-SL-JAVA-1625 " + msg);}); +} + +void ScriptOptionLinesParserCTPG::extractImportScripts(SwigFactory & swigFactory, + std::function throwException) { + parse([&](const std::string& msg){throwException("F-UDF-CL-SL-JAVA-1626 " + msg);}); + + const auto optionIt = m_foundOptions.find(m_keywords.importKeyword()); + if (optionIt != m_foundOptions.end()) { + CTPG::ScriptImporter scriptImporter(swigFactory, m_keywords); + scriptImporter.importScript(m_scriptCode, m_foundOptions, throwException); + //The imported scripts will change the location of the other options in m_foundOptions + //Also there might be new JVM / External Jar options + //=> We need to clear the option map and reset the parser. + m_foundOptions.clear(); + m_needParsing = true; + } +} + +std::string && ScriptOptionLinesParserCTPG::getScriptCode(std::function throwException) { + parse([&](const std::string& msg){throwException("F-UDF-CL-SL-JAVA-1627 " + msg);}); + //Remove all options from script code in reverse order + struct option_location { + size_t pos; + size_t len; + }; + struct comp { + bool operator()(option_location a, option_location b) const { + return a.pos > b.pos; + } + }; + std::set option_locations; + for (const auto & option: m_foundOptions) { + for (const auto & option_loc: option.second) { + option_location loc = { .pos = option_loc.idx_in_source, .len = option_loc.size}; + option_locations.insert(loc); + } + } + for (const auto option_loc: option_locations) { + m_scriptCode.erase(option_loc.pos, option_loc.len); + } + return std::move(m_scriptCode); +} + +void ScriptOptionLinesParserCTPG::parse(std::function throwException) { + if (m_needParsing) { + if(!m_foundOptions.empty()) { + throwException("F-UDF-CL-SL-JAVA-1620 Internal error. Parser result is not empty."); + } + ExecutionGraph::OptionsLineParser::CTPG::parseOptions(m_scriptCode, m_foundOptions, + [&](const char* msg){throwException(std::string("F-UDF-CL-SL-JAVA-1621 ") + msg);}); + m_needParsing = false; + + //Check for unknown options + for (const auto & option: m_foundOptions) { + if (m_keywords.jarKeyword() != option.first && + m_keywords.scriptClassKeyword() != option.first && + m_keywords.importKeyword() != option.first && + m_keywords.jvmKeyword() != option.first) { + std::stringstream ss; + ss << "F-UDF-CL-SL-JAVA-1622 " << "Unexpected option: " << option.first; + throwException(ss.str()); + } + } + } +} + +void ScriptOptionLinesParserCTPG::parseForSingleOption(const std::string key, std::function callback, + std::function throwException) { + parse(throwException); + const auto optionIt = m_foundOptions.find(key); + if (optionIt != m_foundOptions.end()) { + if (optionIt->second.size() != 1) { + std::stringstream ss; + ss << "F-UDF-CL-SL-JAVA-1628 found " << optionIt->second.size() << key << " options" << std::endl; + throwException(ss.str()); + } + callback(optionIt->second[0].value); + } +} + +void ScriptOptionLinesParserCTPG::parseForMultipleOption(const std::string key, std::function callback, + std::function throwException) { + parse(throwException); + const auto optionIt = m_foundOptions.find(key); + if (optionIt != m_foundOptions.end()) { + for (const auto & option : optionIt->second) { + callback(option.value); + } + } +} } //namespace JavaScriptOptions diff --git a/exaudfclient/base/javacontainer/script_options/parser_ctpg.h b/exaudfclient/base/javacontainer/script_options/parser_ctpg.h index 3b71a5ee..7f4bdf58 100644 --- a/exaudfclient/base/javacontainer/script_options/parser_ctpg.h +++ b/exaudfclient/base/javacontainer/script_options/parser_ctpg.h @@ -1,10 +1,53 @@ #ifndef SCRIPTOPTIONLINEPARSERCTPGY_H #define SCRIPTOPTIONLINEPARSERCTPGY_H 1 +#include "base/javacontainer/script_options/parser.h" +#include "base/javacontainer/script_options/keywords.h" +#include "base/script_options_parser/ctpg/script_option_lines_ctpg.h" + + namespace SWIGVMContainers { namespace JavaScriptOptions { +class ScriptOptionLinesParserCTPG : public ScriptOptionsParser { + + public: + ScriptOptionLinesParserCTPG(); + + void prepareScriptCode(const std::string & scriptCode) override; + + void parseForScriptClass(std::function callback, + std::function throwException) override; + + void parseForJvmOptions(std::function callback, + std::function throwException) override; + + void parseForExternalJars(std::function callback, + std::function throwException) override; + + void extractImportScripts(SwigFactory & swigFactory, + std::function throwException) override; + + std::string && getScriptCode(std::function throwException) override; + + private: + void parse(std::function throwException); + + void parseForSingleOption(const std::string key, std::function callback, + std::function throwException); + void parseForMultipleOption(const std::string key, std::function callback, + std::function throwException); + + void importScripts(SwigFactory & swigFactory, + std::function throwException); + + private: + std::string m_scriptCode; + Keywords m_keywords; + ExecutionGraph::OptionsLineParser::CTPG::options_map_t m_foundOptions; + bool m_needParsing; +}; } //namespace JavaScriptOptions diff --git a/exaudfclient/base/javacontainer/script_options/parser_ctpg_script_importer.cc b/exaudfclient/base/javacontainer/script_options/parser_ctpg_script_importer.cc new file mode 100644 index 00000000..c7dee049 --- /dev/null +++ b/exaudfclient/base/javacontainer/script_options/parser_ctpg_script_importer.cc @@ -0,0 +1,82 @@ +#include "base/javacontainer/script_options/parser_ctpg_script_importer.h" +#include "base/swig_factory/swig_factory.h" +#include "base/debug_message.h" +#include +#include + +namespace ctpg_parser = ExecutionGraph::OptionsLineParser::CTPG; + +namespace SWIGVMContainers { + +namespace JavaScriptOptions { + +namespace CTPG { + +ScriptImporter::ScriptImporter(SwigFactory & swigFactory, Keywords & keywords) +: m_importedScriptChecksums() +, m_swigFactory(swigFactory) +, m_metaData() +, m_keywords(keywords) {} + +void ScriptImporter::importScript(std::string & scriptCode, ctpg_parser::options_map_t & options, + std::function throwException) { + const auto optionIt = options.find(std::string(m_keywords.importKeyword())); + if (optionIt != options.end()) { + m_importedScriptChecksums.addScript(scriptCode.c_str()); + //Sort options from first in script to last in script + std::sort(optionIt->second.begin(), optionIt->second.end(), + [](const ctpg_parser::ScriptOption& first, const ctpg_parser::ScriptOption& second) + { + return first.idx_in_source < second.idx_in_source; + }); + struct ReplacedScripts { + ReplacedScripts(ReplacedScripts&&) = default; + std::string script; + size_t origPos; + size_t origLen; + }; + std::vector replacedScripts; + replacedScripts.reserve(optionIt->second.size()); + //In order to continue compatibility with legacy implementation we must collect import scripts in forward direction + //but then replace in reverse direction (in order to keep consistency of positions) + for (const auto & option: optionIt->second) { + const char *importScriptCode = findImportScript(option.value, throwException); + std::string importScriptCodeStr; + if (m_importedScriptChecksums.addScript(importScriptCode)) { + // Script has not been imported yet + // If this imported script contains %import statements + // they will be resolved in the next recursion. + ctpg_parser::options_map_t newOptions; + ExecutionGraph::OptionsLineParser::CTPG::parseOptions(importScriptCode, newOptions, + [&](const char* msg){throwException(std::string("F-UDF-CL-SL-JAVA-1630 ") + msg);}); + importScriptCodeStr.assign(importScriptCode); + importScript(importScriptCodeStr, newOptions, throwException); + } + ReplacedScripts replacedScript = {.script = std::move(importScriptCodeStr), .origPos = option.idx_in_source, .origLen = option.size }; + replacedScripts.push_back(std::move(replacedScript)); + } + for (auto optionIt = replacedScripts.rbegin(); optionIt != replacedScripts.rend(); optionIt++) { + scriptCode.replace(optionIt->origPos, optionIt->origLen, optionIt->script); + } + } +} + +const char* ScriptImporter::findImportScript(const std::string & scriptKey, + std::function throwException) { + if (!m_metaData) { + m_metaData.reset(m_swigFactory.makeSwigMetadata()); + if (!m_metaData) + throwException("F-UDF-CL-SL-JAVA-1631: Failure while importing scripts"); + } + const char *importScriptCode = m_metaData->moduleContent(scriptKey.c_str()); + const char *exception = m_metaData->checkException(); + if (exception) + throwException("F-UDF-CL-SL-JAVA-1632: " + std::string(exception)); + return importScriptCode; +} + +} //namespace CTPG + +} //namespace JavaScriptOptions + +} //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/parser_ctpg_script_importer.h b/exaudfclient/base/javacontainer/script_options/parser_ctpg_script_importer.h new file mode 100644 index 00000000..dd87c5f6 --- /dev/null +++ b/exaudfclient/base/javacontainer/script_options/parser_ctpg_script_importer.h @@ -0,0 +1,43 @@ +#ifndef SCRIPTOPTIONLINEPARSERCTPGSCRIPTIMPORTER_H +#define SCRIPTOPTIONLINEPARSERCTPGSCRIPTIMPORTER_H 1 + +#include "base/javacontainer/script_options/checksum.h" +#include "base/javacontainer/script_options/keywords.h" +#include "base/exaudflib/swig/swig_meta_data.h" +#include "base/script_options_parser/ctpg/script_option_lines_ctpg.h" +#include + + +namespace SWIGVMContainers { + + struct SwigFactory; + +namespace JavaScriptOptions { + +namespace CTPG { + +class ScriptImporter { + + public: + ScriptImporter(SwigFactory & swigFactory, Keywords & keywords); + + void importScript(std::string & scriptCode, + ExecutionGraph::OptionsLineParser::CTPG::options_map_t & options, + std::function throwException); + + private: + const char* findImportScript(const std::string & scriptKey, std::function throwException); + private: + Checksum m_importedScriptChecksums; + SwigFactory & m_swigFactory; + std::unique_ptr m_metaData; + Keywords & m_keywords; +}; + +} //namespace CTPG + +} //namespace JavaScriptOptions + +} //namespace SWIGVMContainers + +#endif //SCRIPTOPTIONLINEPARSERCTPGSCRIPTIMPORTER_H diff --git a/exaudfclient/base/javacontainer/script_options/parser_legacy.cc b/exaudfclient/base/javacontainer/script_options/parser_legacy.cc index 212fa455..741cd26f 100644 --- a/exaudfclient/base/javacontainer/script_options/parser_legacy.cc +++ b/exaudfclient/base/javacontainer/script_options/parser_legacy.cc @@ -14,7 +14,7 @@ ScriptOptionLinesParserLegacy::ScriptOptionLinesParserLegacy() : m_whitespace(" \t\f\v") , m_lineend(";") , m_scriptCode() -, m_keywords() {} +, m_keywords(true) {} void ScriptOptionLinesParserLegacy::prepareScriptCode(const std::string & scriptCode) { m_scriptCode = scriptCode; @@ -135,7 +135,7 @@ void ScriptOptionLinesParserLegacy::parseForScriptClass(std::function callback, std::function throwException) { - parseForMultipleOptions(m_keywords.jvmOptionKeyword(), + parseForMultipleOptions(m_keywords.jvmKeyword(), [&](const std::string& value, size_t pos){callback(value);}, [&](const std::string& msg){throwException("F-UDF-CL-SL-JAVA-1612" + msg);}); } @@ -147,11 +147,11 @@ void ScriptOptionLinesParserLegacy::parseForExternalJars(std::function throwException) { return std::move(m_scriptCode); } -void ScriptOptionLinesParserLegacy::parseForSingleOption(const std::string keyword, +void ScriptOptionLinesParserLegacy::parseForSingleOption(const std::string & keyword, std::function callback, std::function throwException) { size_t pos; @@ -169,7 +169,7 @@ void ScriptOptionLinesParserLegacy::parseForSingleOption(const std::string keywo } } -void ScriptOptionLinesParserLegacy::parseForMultipleOptions(const std::string keyword, +void ScriptOptionLinesParserLegacy::parseForMultipleOptions(const std::string & keyword, std::function callback, std::function throwException) { size_t pos; diff --git a/exaudfclient/base/javacontainer/script_options/parser_legacy.h b/exaudfclient/base/javacontainer/script_options/parser_legacy.h index 8928d21a..b60ca0e3 100644 --- a/exaudfclient/base/javacontainer/script_options/parser_legacy.h +++ b/exaudfclient/base/javacontainer/script_options/parser_legacy.h @@ -29,13 +29,13 @@ class ScriptOptionLinesParserLegacy : public ScriptOptionsParser { void extractImportScripts(SwigFactory & swigFactory, std::function throwException) override; - std::string && getScriptCode() override; + std::string && getScriptCode(std::function throwException) override; private: - void parseForSingleOption(const std::string key, + void parseForSingleOption(const std::string& key, std::function callback, std::function throwException); - void parseForMultipleOptions(const std::string key, + void parseForMultipleOptions(const std::string& key, std::function callback, std::function throwException); diff --git a/exaudfclient/base/javacontainer/test/BUILD b/exaudfclient/base/javacontainer/test/BUILD index 32874b9f..6cba7658 100644 --- a/exaudfclient/base/javacontainer/test/BUILD +++ b/exaudfclient/base/javacontainer/test/BUILD @@ -10,14 +10,26 @@ java_test( deps = [":ExaStackTraceCleaner"] ) +JAVACONTAINER_TEST_SRCS = ["cpp/javacontainer_test.cc", "cpp/exaudf_wrapper.cc", "cpp/javavm_test.cc", "cpp/javavm_test.h", + "cpp/swig_factory_test.h", "cpp/swig_factory_test.cc"] cc_test( - name = "javacontainer-test", - srcs = ["cpp/javacontainer_test.cc", "cpp/exaudf_wrapper.cc", "cpp/javavm_test.cc", "cpp/javavm_test.h", - "cpp/swig_factory_test.h", "cpp/swig_factory_test.cc"], + name = "javacontainer-test-legacy-parser", + srcs = JAVACONTAINER_TEST_SRCS, deps = [ "//base/javacontainer:javacontainer", "@googletest//:gtest_main", ], data = ["test.jar", "other_test.jar"] -) \ No newline at end of file +) + +cc_test( + name = "javacontainer-test-ctpg-parser", + srcs = JAVACONTAINER_TEST_SRCS, + deps = [ + "//base/javacontainer:javacontainer", + "@googletest//:gtest_main", + ], + defines = ["USE_CTPG_PARSER"], + data = ["test.jar", "other_test.jar"] +) diff --git a/exaudfclient/base/javacontainer/test/cpp/javacontainer_test.cc b/exaudfclient/base/javacontainer/test/cpp/javacontainer_test.cc index ff772f68..4b98c4f5 100644 --- a/exaudfclient/base/javacontainer/test/cpp/javacontainer_test.cc +++ b/exaudfclient/base/javacontainer/test/cpp/javacontainer_test.cc @@ -369,7 +369,10 @@ TEST(JavaContainer, import_script_script_class_option_ignored) { EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); const std::string expected_script_code = "package com.exasol;\r\n" - "%scriptclass com.exasol.udf_profiling.UdfProfiler;\n" +#ifndef USE_CTPG_PARSER //The parsers behave differently: The legacy parser incorrectly keeps imported scriptclass options + "%scriptclass com.exasol.udf_profiling.UdfProfiler;" +#endif + "\n" "class OtherClass {\n" "static void doSomething() {\n\n" " }\n" diff --git a/exaudfclient/base/javacontainer/test/cpp/javavm_test.cc b/exaudfclient/base/javacontainer/test/cpp/javavm_test.cc index 9ac82a59..f4ec7f39 100644 --- a/exaudfclient/base/javacontainer/test/cpp/javavm_test.cc +++ b/exaudfclient/base/javacontainer/test/cpp/javavm_test.cc @@ -20,7 +20,11 @@ JavaVMTest::JavaVMTest(std::string scriptCode, SwigFactoryTestImpl & swigFactory void JavaVMTest::run(std::string scriptCode, SwigFactoryTestImpl & swigFactory) { char* script_code = ::strdup(scriptCode.c_str()); SWIGVMContainers::SWIGVM_params->script_code = script_code; - SWIGVMContainers::JavaVMImpl javaVMImpl(false, true, swigFactory); + bool useCTPGParser = false; +#ifdef USE_CTPG_PARSER + useCTPGParser = true; +#endif + SWIGVMContainers::JavaVMImpl javaVMImpl(false, true, swigFactory, useCTPGParser); javaVMInternalStatus.m_exaJavaPath = javaVMImpl.m_exaJavaPath; javaVMInternalStatus.m_localClasspath = javaVMImpl.m_localClasspath; javaVMInternalStatus.m_scriptCode = javaVMImpl.m_scriptCode; diff --git a/exaudfclient/base/javacontainer/test/cpp/swig_factory_test.cc b/exaudfclient/base/javacontainer/test/cpp/swig_factory_test.cc index 7dbb6ee7..aa46fa7d 100644 --- a/exaudfclient/base/javacontainer/test/cpp/swig_factory_test.cc +++ b/exaudfclient/base/javacontainer/test/cpp/swig_factory_test.cc @@ -14,8 +14,8 @@ class SWIGMetadataTest : public SWIGVMContainers::SWIGMetadataIf { public: SWIGMetadataTest(const std::map & moduleContent, const std::string & exceptionMsg) - : m_moduleContent(moduleContent) - , m_exceptionMsg(exceptionMsg) {} + : m_exceptionMsg(exceptionMsg) + , m_moduleContent(moduleContent) {} virtual const char* databaseName() { throw NotImplemented("databaseName"); return nullptr;} virtual const char* databaseVersion() { throw NotImplemented("databaseVersion"); return nullptr;} virtual const char* scriptName() { throw NotImplemented("scriptName"); return nullptr;} diff --git a/exaudfclient/base/script_options_parser/ctpg/script_option_lines_ctpg.h b/exaudfclient/base/script_options_parser/ctpg/script_option_lines_ctpg.h index c16a21d9..d01c032d 100644 --- a/exaudfclient/base/script_options_parser/ctpg/script_option_lines_ctpg.h +++ b/exaudfclient/base/script_options_parser/ctpg/script_option_lines_ctpg.h @@ -16,8 +16,6 @@ namespace OptionsLineParser namespace CTPG { -class ParserResult; - struct ScriptOption { std::string value; size_t idx_in_source; diff --git a/exaudfclient/exaudfclient.cc b/exaudfclient/exaudfclient.cc index 1b9a63be..f9ab536f 100644 --- a/exaudfclient/exaudfclient.cc +++ b/exaudfclient/exaudfclient.cc @@ -163,7 +163,7 @@ int main(int argc, char **argv) { } else if (strcmp(argv[2], "lang=java")==0) { #ifdef ENABLE_JAVA_VM - vmMaker = [&](){return new SWIGVMContainers::JavaVMach(false, swigFactory);}; + vmMaker = [&](){return new SWIGVMContainers::JavaVMach(false, swigFactory, false);}; #else throw SWIGVM::exception("this exaudfclient has been compilied without Java support"); #endif