Factor out handling the lib-module's data path

Provide injection of @LibModuleData Path which resolves into
$SITE/data/saml. A similar logic exists in Gerrit core for the
@PluginData Path binding but this code is, unfortunately, not exposed to
modules.  For that reason this commit copies the logic for the
plugin data directory creation in the LibModuleDataDirUtil class.

The code in LibModuleDataDirUtil honors an already existing directory,
also when it exists as a symlink.

Change-Id: I39cd43a27dec824827bec313b06d0a47271f177c
diff --git a/src/main/java/com/googlesource/gerrit/plugins/saml/LibModuleData.java b/src/main/java/com/googlesource/gerrit/plugins/saml/LibModuleData.java
new file mode 100644
index 0000000..c84fe7a
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/saml/LibModuleData.java
@@ -0,0 +1,24 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.saml;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.google.inject.BindingAnnotation;
+import java.lang.annotation.Retention;
+
+@Retention(RUNTIME)
+@BindingAnnotation
+public @interface LibModuleData {}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/saml/Module.java b/src/main/java/com/googlesource/gerrit/plugins/saml/Module.java
index f39daad..55aef92 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/saml/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/saml/Module.java
@@ -16,10 +16,13 @@
 
 import com.google.common.collect.Sets;
 import com.google.gerrit.server.config.AuthConfig;
+import com.google.gerrit.server.config.SitePath;
 import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 import com.google.inject.ProvisionException;
 import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.saml.pgm.LibModuleDataDirUtil;
+import java.nio.file.Path;
 import java.util.HashSet;
 import java.util.Set;
 import org.pac4j.saml.client.SAML2Client;
@@ -52,4 +55,10 @@
 
     return authHeaders;
   }
+
+  @Provides
+  @LibModuleData
+  Path getLibModuleData(@SitePath Path sitePath) {
+    return LibModuleDataDirUtil.createLibModuleDataDir(sitePath);
+  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/saml/SamlClientProvider.java b/src/main/java/com/googlesource/gerrit/plugins/saml/SamlClientProvider.java
index 51d2cd7..9d5d047 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/saml/SamlClientProvider.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/saml/SamlClientProvider.java
@@ -15,18 +15,14 @@
 package com.googlesource.gerrit.plugins.saml;
 
 import static com.google.common.base.Preconditions.checkNotNull;
-import static com.googlesource.gerrit.plugins.saml.SamlWebFilter.SAML;
 import static com.googlesource.gerrit.plugins.saml.SamlWebFilter.SAML_CALLBACK;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.common.Nullable;
 import com.google.gerrit.server.config.CanonicalWebUrl;
-import com.google.gerrit.server.config.SitePaths;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
-import java.io.IOException;
-import java.nio.file.Files;
 import java.nio.file.Path;
 import org.pac4j.saml.client.SAML2Client;
 import org.pac4j.saml.config.SAML2Configuration;
@@ -39,14 +35,16 @@
 
   private final SamlConfig samlConfig;
   private final String canonicalUrl;
-  private final SitePaths sitePaths;
+  private final Path libModuleDataDir;
 
   @Inject
   public SamlClientProvider(
-      @CanonicalWebUrl @Nullable String canonicalUrl, SitePaths sitePaths, SamlConfig samlConfig) {
+      @CanonicalWebUrl @Nullable String canonicalUrl,
+      SamlConfig samlConfig,
+      @LibModuleData Path libModuleDataDir) {
     this.samlConfig = samlConfig;
     this.canonicalUrl = canonicalUrl;
-    this.sitePaths = sitePaths;
+    this.libModuleDataDir = libModuleDataDir;
   }
 
   @Override
@@ -81,14 +79,6 @@
   }
 
   public Path getSpMetadataPath() {
-    return ensureExists(sitePaths.data_dir).resolve("sp-metadata.xml");
-  }
-
-  private static Path ensureExists(Path dataDir) {
-    try {
-      return Files.createDirectories(dataDir.resolve(SAML));
-    } catch (IOException e) {
-      throw new IllegalStateException("Unable to create data directory for the SAML-plugin.", e);
-    }
+    return libModuleDataDir.resolve("sp-metadata.xml");
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/saml/pgm/LibModuleDataDirUtil.java b/src/main/java/com/googlesource/gerrit/plugins/saml/pgm/LibModuleDataDirUtil.java
new file mode 100644
index 0000000..699ad81
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/saml/pgm/LibModuleDataDirUtil.java
@@ -0,0 +1,34 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.saml.pgm;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+public class LibModuleDataDirUtil {
+
+  public static Path createLibModuleDataDir(Path sitePath) {
+    Path dataDir = sitePath.resolve("data/saml");
+    if (!Files.isDirectory(dataDir)) {
+      try {
+        Files.createDirectories(dataDir);
+      } catch (IOException e) {
+        throw new RuntimeException(String.format("Cannot create %s", dataDir.toAbsolutePath()), e);
+      }
+    }
+    return dataDir;
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/saml/pgm/SamlMetadataCreator.java b/src/main/java/com/googlesource/gerrit/plugins/saml/pgm/SamlMetadataCreator.java
index 33a39e4..d9f6438 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/saml/pgm/SamlMetadataCreator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/saml/pgm/SamlMetadataCreator.java
@@ -14,6 +14,8 @@
 
 package com.googlesource.gerrit.plugins.saml.pgm;
 
+import static com.googlesource.gerrit.plugins.saml.pgm.LibModuleDataDirUtil.createLibModuleDataDir;
+
 import com.google.gerrit.server.config.SitePaths;
 import com.googlesource.gerrit.plugins.saml.SamlClientProvider;
 import com.googlesource.gerrit.plugins.saml.SamlConfig;
@@ -89,7 +91,8 @@
       Config cfg = parseGerritConfig();
       String canonicalWebUrl = cfg.getString("gerrit", null, "canonicalWebUrl");
       samlClientProvider =
-          new SamlClientProvider(canonicalWebUrl, sitePaths, new SamlConfig(cfg, sitePaths));
+          new SamlClientProvider(
+              canonicalWebUrl, new SamlConfig(cfg, sitePaths), createLibModuleDataDir(sitePath));
     } catch (ConfigInvalidException | IOException e) {
       throw new ConfigInvalidException("Unable to parse Gerrit's configuration.", e);
     }