cui/source/options/optjava.cxx |   19 +++++++++-----
 include/jvmfwk/framework.hxx   |   11 ++++++++
 jvmfwk/source/framework.cxx    |   55 +++++++++++++++++++++++++++++++++++++++--
 3 files changed, 77 insertions(+), 8 deletions(-)

New commits:
commit 7795a2adc0a724220440dca997495043902f1384
Author:     Samuel Mehrbrodt <[email protected]>
AuthorDate: Mon Jun 12 14:31:45 2023 +0200
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Wed Jun 21 00:45:53 2023 +0200

    Allow bootstrap variables in Java user classpath settings, 2nd try
    
    Add a second mode: When a classpath starts with '$', bootstrap variables 
are recognized.
    The classpath must then be provided as URL, not native path.
    
    Change-Id: Idcc229a2b4e9a512b0e712ea932a6e4293907db3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152899
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <[email protected]>

diff --git a/cui/source/options/optjava.cxx b/cui/source/options/optjava.cxx
index c1528138f326..17f128ce9b3b 100644
--- a/cui/source/options/optjava.cxx
+++ b/cui/source/options/optjava.cxx
@@ -33,6 +33,7 @@
 
 #include <officecfg/Office/Common.hxx>
 #include <osl/file.hxx>
+#include <rtl/bootstrap.hxx>
 
 #include <strings.hrc>
 #include <vcl/svapp.hxx>
@@ -941,16 +942,22 @@ void SvxJavaClassPathDlg::SetClassPath( const OUString& 
_rPath )
     m_xPathList->clear();
     if (!_rPath.isEmpty())
     {
-        sal_Int32 nIdx = 0;
-        do
+        std::vector paths = jfw_convertUserPathList(_rPath);
+        for (auto const& path : paths)
         {
-            OUString sToken = _rPath.getToken( 0, CLASSPATH_DELIMITER, nIdx );
             OUString sURL;
-            osl::FileBase::getFileURLFromSystemPath(sToken, sURL); // best 
effort
+            if (path.startsWith("$"))
+            {
+                sURL = path;
+                rtl::Bootstrap::expandMacros(sURL);
+            }
+            else
+            {
+                osl::FileBase::getFileURLFromSystemPath(path, sURL);
+            }
             INetURLObject aURL( sURL );
-            m_xPathList->append("", sToken, 
SvFileInformationManager::GetImageId(aURL));
+            m_xPathList->append("", path, 
SvFileInformationManager::GetImageId(aURL));
         }
-        while (nIdx>=0);
         // select first entry
         m_xPathList->select(0);
     }
diff --git a/include/jvmfwk/framework.hxx b/include/jvmfwk/framework.hxx
index 8f7eb8a2ad29..d3cf01791e6b 100644
--- a/include/jvmfwk/framework.hxx
+++ b/include/jvmfwk/framework.hxx
@@ -345,6 +345,17 @@ JVMFWK_DLLPUBLIC javaFrameworkError 
jfw_findAndSelectJRE(std::unique_ptr<JavaInf
 JVMFWK_DLLPUBLIC javaFrameworkError
 jfw_findAllJREs(std::vector<std::unique_ptr<JavaInfo>>* parInfo);
 
+/**
+ * Convert colon-separated userClassPath which might contain bootstrap 
variables
+ * (which also might contain colons) to a list of classPaths, keeping 
bootstrap variables intact.
+ *
+ * FIXME: Nested or multiple occurrences of ${...:...:...} are currently not 
supported.
+ *
+ * @param sUserPath colon-separated string of user classpaths
+ * @return list of user classpaths
+ */
+JVMFWK_DLLPUBLIC std::vector<OUString> jfw_convertUserPathList(OUString const& 
sUserPath);
+
 /** determines if a path points to a Java installation.
 
    <p>If the path belongs to a JRE installation then it returns the
diff --git a/jvmfwk/source/framework.cxx b/jvmfwk/source/framework.cxx
index 5f83e7be739e..cfeca1f72904 100644
--- a/jvmfwk/source/framework.cxx
+++ b/jvmfwk/source/framework.cxx
@@ -23,11 +23,12 @@
 #include <cassert>
 #include <memory>
 
+#include <rtl/bootstrap.hxx>
 #include <rtl/ref.hxx>
 #include <rtl/ustring.hxx>
 #include <osl/diagnose.h>
-#ifdef _WIN32
 #include <osl/file.hxx>
+#ifdef _WIN32
 #include <osl/process.h>
 #endif
 #include <osl/thread.hxx>
@@ -132,6 +133,40 @@ javaFrameworkError 
jfw_findAllJREs(std::vector<std::unique_ptr<JavaInfo>> *pparI
     }
 }
 
+std::vector<OUString> jfw_convertUserPathList(OUString const& sUserPath)
+{
+    std::vector<OUString> result;
+    sal_Int32 nIdx = 0;
+    do
+    {
+        sal_Int32 nextColon = sUserPath.indexOf(SAL_PATHSEPARATOR, nIdx);
+        OUString sToken(sUserPath.subView(nIdx, nextColon > 0 ? nextColon - 
nIdx
+                                                              : 
sUserPath.getLength() - nIdx));
+
+        // Check if we are in bootstrap variable mode (class path starts with 
'$').
+        // Then the class path must be in URL format.
+        if (sToken.startsWith("$"))
+        {
+            // Detect open bootstrap variables - they might contain colons - 
we need to skip those.
+            sal_Int32 nBootstrapVarStart = sToken.indexOf("${");
+            if (nBootstrapVarStart >= 0)
+            {
+                sal_Int32 nBootstrapVarEnd = sToken.indexOf("}", 
nBootstrapVarStart);
+                if (nBootstrapVarEnd == -1)
+                {
+                    // Current colon is part of bootstrap variable - skip it!
+                    nextColon = sUserPath.indexOf(SAL_PATHSEPARATOR, nextColon 
+ 1);
+                    sToken = sUserPath.subView(nIdx, nextColon > 0 ? nextColon 
- nIdx
+                                                                   : 
sUserPath.getLength() - nIdx);
+                }
+            }
+        }
+        result.emplace_back(sToken);
+        nIdx = nextColon + 1;
+    } while (nIdx > 0);
+    return result;
+}
+
 javaFrameworkError jfw_startVM(
     JavaInfo const * pInfo, std::vector<OUString> const & arOptions,
     JavaVM ** ppVM, JNIEnv ** ppEnv)
@@ -185,7 +220,23 @@ javaFrameworkError jfw_startVM(
                     return JFW_E_NEED_RESTART;
 
                 vmParams = settings.getVmParametersUtf8();
-                sUserClassPath = 
jfw::makeClassPathOption(settings.getUserClassPath());
+                // Expand user classpath (might contain bootstrap vars)
+                OUString sUserPath(settings.getUserClassPath());
+                std::vector paths = jfw_convertUserPathList(sUserPath);
+                OUString sUserPathExpanded;
+                for (auto& path : paths)
+                {
+                    if (!sUserPathExpanded.isEmpty())
+                        sUserPathExpanded += OUStringChar(SAL_PATHSEPARATOR);
+                    if (path.startsWith("$"))
+                    {
+                        OUString sURL = path;
+                        rtl::Bootstrap::expandMacros(sURL);
+                        osl::FileBase::getSystemPathFromFileURL(sURL, path);
+                    }
+                    sUserPathExpanded += path;
+                }
+                sUserClassPath = jfw::makeClassPathOption(sUserPathExpanded);
             } // end mode FWK_MODE_OFFICE
             else if (mode == jfw::JFW_MODE_DIRECT)
             {

Reply via email to