Support saving/merging global trusted authority preferences

https://github.com/eclipse-equinox/p2/issues/235
diff --git a/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/core/P2Util.java b/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/core/P2Util.java
index 59e9745..00a17a8 100644
--- a/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/core/P2Util.java
+++ b/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/core/P2Util.java
@@ -56,10 +56,12 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.nio.file.Files;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -228,6 +230,11 @@
       currentCertificateChecker.setTrustAlways(trustAlways);
       currentCertificateChecker.persistTrustedCertificates(trustedCertificates);
       currentCertificateChecker.persistTrustedKeys(trustedKeys);
+
+      if (TrustAuthoritySupport.ENABLED)
+      {
+        TrustAuthoritySupport.mergeGlobalTrustPreferences(profile, globalTrustFolder);
+      }
     }
   }
 
@@ -333,6 +340,11 @@
           }
         }
       }
+
+      if (TrustAuthoritySupport.ENABLED)
+      {
+        TrustAuthoritySupport.saveGlobalTrustPreferences(profile, trustFolder, strict);
+      }
     }
   }
 
@@ -698,4 +710,90 @@
   {
     public boolean matches(IVersionedId versionedId);
   }
+
+  @SuppressWarnings({ "restriction", "nls" })
+  private static class TrustAuthoritySupport
+  {
+    public static final boolean ENABLED;
+
+    static
+    {
+      boolean enabled = false;
+      try
+      {
+        org.eclipse.equinox.internal.p2.engine.phases.AuthorityChecker.class.getName();
+        enabled = true;
+      }
+      catch (Exception ex)
+      {
+        //$FALL-THROUGH$
+      }
+      ENABLED = enabled;
+    }
+
+    public static org.eclipse.equinox.internal.p2.engine.phases.AuthorityChecker createAuthorityChecker(Profile profile)
+    {
+      org.eclipse.equinox.internal.p2.engine.phases.AuthorityChecker authorityChecker = new org.eclipse.equinox.internal.p2.engine.phases.AuthorityChecker(
+          profile.getProvisioningAgent(), profile);
+      return authorityChecker;
+    }
+
+    public static void mergeGlobalTrustPreferences(Profile profile, File globalTrustFolder)
+    {
+      // Copy the global preference settings into the current agent's profile preferences.
+      org.eclipse.equinox.internal.p2.engine.phases.AuthorityChecker authorityChecker = createAuthorityChecker(profile);
+
+      Map<String, String> properties = PropertiesUtil.getProperties(new File(globalTrustFolder, PREFERENCES_FILE_NAME));
+      boolean trustAllAuthorities = "true"
+          .equals(properties.getOrDefault(org.eclipse.equinox.internal.p2.engine.phases.AuthorityChecker.TRUST_ALL_AUTHORITIES, "false"));
+      List<String> trustedAuthoritiesProperty = Arrays
+          .asList(properties.getOrDefault(org.eclipse.equinox.internal.p2.engine.phases.AuthorityChecker.TRUSTED_AUTHORITIES_PROPERTY, "").split("\\s+"));
+      Set<URI> trustedAuthorities = new LinkedHashSet<>(authorityChecker.getPreferenceTrustedAuthorities());
+      for (String authority : trustedAuthoritiesProperty)
+      {
+        try
+        {
+          if (!authority.isBlank())
+          {
+            trustedAuthorities.add(new URI(authority));
+          }
+        }
+        catch (URISyntaxException ex)
+        {
+          //$FALL-THROUGH$
+        }
+      }
+
+      authorityChecker.setTrustAlways(trustAllAuthorities);
+      authorityChecker.persistTrustedAuthorities(trustedAuthorities);
+    }
+
+    public static void saveGlobalTrustPreferences(Profile profile, File trustFolder, boolean strict)
+    {
+      org.eclipse.equinox.internal.p2.engine.phases.AuthorityChecker authorityChecker = createAuthorityChecker(profile);
+
+      boolean trustAlways = authorityChecker.isTrustAlways();
+      Set<URI> trustedAuthorities = authorityChecker.getPreferenceTrustedAuthorities();
+
+      File propertiesFile = new File(trustFolder, PREFERENCES_FILE_NAME);
+      Map<String, String> properties = PropertiesUtil.getProperties(propertiesFile);
+      Set<String> trustedAuthoritiesProperty = new LinkedHashSet<>();
+      if (!strict)
+      {
+        trustedAuthoritiesProperty.addAll(Arrays
+            .asList(properties.getOrDefault(org.eclipse.equinox.internal.p2.engine.phases.AuthorityChecker.TRUSTED_AUTHORITIES_PROPERTY, "").split("\\s+")));
+        trustedAuthoritiesProperty.remove("");
+      }
+
+      for (URI uri : trustedAuthorities)
+      {
+        trustedAuthoritiesProperty.add(uri.toString());
+      }
+
+      properties.put(org.eclipse.equinox.internal.p2.engine.phases.AuthorityChecker.TRUST_ALL_AUTHORITIES, Boolean.toString(trustAlways));
+      properties.put(org.eclipse.equinox.internal.p2.engine.phases.AuthorityChecker.TRUSTED_AUTHORITIES_PROPERTY, String.join(" ", trustedAuthoritiesProperty));
+
+      PropertiesUtil.saveProperties(propertiesFile, properties, false);
+    }
+  }
 }
diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/messages.properties b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/messages.properties
index c2b4d9c..125f703 100644
--- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/messages.properties
+++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/messages.properties
@@ -135,7 +135,7 @@
 SimpleInstallerDialog_SwitchIndex_label=SWITCH CATALOG INDEX
 SimpleInstallerDialog_SwitchToAdvancedMode_message=Switch to advanced mode
 SimpleInstallerDialog_Trust_label=TRUST
-SimpleInstallerDialog_Trust_message=Manage the trusted keys and certificates
+SimpleInstallerDialog_Trust_message=Manage the trusted keys, certificates, and authorities
 SimpleInstallerDialog_Update_label=UPDATE
 SimpleInstallerDialog_UpdateSearcher_job=Simple Update Searcher
 SimpleInstallerDialog_WebLinks_label=WEB LINKS
@@ -221,7 +221,7 @@
 SimpleVariablePage_UndefinedVariables_exception=Undefined variables: {0}
 SimpleVariablePage_UndefinedVariables_title=Undefined Variables
 SimpleVariablePage_UndefinedVersiables_message=The variables {0} are undefined. You likely declared them in your ''user.setup'' file without appropriate restrictions, so that you can''t use the installer''s simple mode anymore.\n\nDo you want to switch to the advanced mode now?
-TrustDialog_description=Manage the trusted certificates and keys
+TrustDialog_description=Manage the trusted certificates and keys used for signing artifacts and the trusted authorities used for downloading content
 TrustDialog_title=Trust
 URISchemeDialog_Application_label=Application
 URISchemeDialog_Apply_label=Apply
diff --git a/plugins/org.eclipse.oomph.setup.p2/src/org/eclipse/oomph/setup/p2/impl/P2TaskImpl.java b/plugins/org.eclipse.oomph.setup.p2/src/org/eclipse/oomph/setup/p2/impl/P2TaskImpl.java
index 961945b..192e421 100644
--- a/plugins/org.eclipse.oomph.setup.p2/src/org/eclipse/oomph/setup/p2/impl/P2TaskImpl.java
+++ b/plugins/org.eclipse.oomph.setup.p2/src/org/eclipse/oomph/setup/p2/impl/P2TaskImpl.java
@@ -941,7 +941,6 @@
       Profile selfProfile = P2Util.getAgentManager().getCurrentAgent().getCurrentProfile();
       if (selfProfile != null)
       {
-
         if (selfProfile.getAgent() != profile.getAgent())
         {
           P2Util.copyTrustPreferences(profile, selfProfile);