This is an automated email from the ASF dual-hosted git repository.

kwin pushed a commit to branch feature/SLING-8291_expose-error
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-provider-installhook.git

commit 19eba2c26f323ca7851c41530ec1257264d2a2f1
Author: Georg Henzler <[email protected]>
AuthorDate: Tue Aug 21 17:15:34 2018 +0200

    SLING-7790 Introduced package property "installPathRegex" to control
    what bundles/configs are taken into consideration and runmode support
---
 pom.xml                                            |   6 ++
 .../provider/installhook/OsgiInstallerHook.java    | 113 ++++++++++++++++-----
 2 files changed, 91 insertions(+), 28 deletions(-)

diff --git a/pom.xml b/pom.xml
index 820c8bb..533af9b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -86,6 +86,12 @@
                        <version>3.6.8</version>
                        <scope>provided</scope>
                </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.settings</artifactId>
+            <version>1.0.0</version>
+            <scope>provided</scope>
+        </dependency>          
                <dependency>
                        <groupId>org.osgi</groupId>
                        <artifactId>osgi.core</artifactId>
diff --git 
a/src/main/java/org/apache/sling/installer/provider/installhook/OsgiInstallerHook.java
 
b/src/main/java/org/apache/sling/installer/provider/installhook/OsgiInstallerHook.java
index 1245725..362ae6e 100644
--- 
a/src/main/java/org/apache/sling/installer/provider/installhook/OsgiInstallerHook.java
+++ 
b/src/main/java/org/apache/sling/installer/provider/installhook/OsgiInstallerHook.java
@@ -21,6 +21,7 @@ package org.apache.sling.installer.provider.installhook;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -45,10 +46,12 @@ import org.apache.jackrabbit.vault.fs.io.ImportOptions;
 import org.apache.jackrabbit.vault.packaging.InstallContext;
 import org.apache.jackrabbit.vault.packaging.InstallHook;
 import org.apache.jackrabbit.vault.packaging.PackageException;
+import org.apache.jackrabbit.vault.packaging.PackageProperties;
 import org.apache.jackrabbit.vault.packaging.VaultPackage;
 import org.apache.sling.installer.api.InstallableResource;
 import org.apache.sling.installer.api.OsgiInstaller;
 import org.apache.sling.installer.api.event.InstallationListener;
+import org.apache.sling.settings.SlingSettingsService;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
@@ -77,28 +80,57 @@ public class OsgiInstallerHook implements InstallHook {
 
        public static final String URL_SCHEME = "jcrinstall";
        public static final String CONFIG_SUFFIX = ".config";
+       public static final String JAR_SUFFIX = ".jar";
+
+       public static final String PACKAGE_PROP_INSTALL_PATH_REGEX = 
"installPathRegex";
+
+       public static final String DOT = ".";
+       public static final int PRIORITY_INSTALL_HOOK = 2000;
 
        private InstallHookLogger logger = new InstallHookLogger();
 
        @Override
        public void execute(InstallContext context) throws PackageException {
 
+               VaultPackage vaultPackage = context.getPackage();
+               PackageProperties packageProperties = 
vaultPackage.getProperties();
+               String installPathRegex = 
packageProperties.getProperty(PACKAGE_PROP_INSTALL_PATH_REGEX);
+
                ServiceReference<OsgiInstaller> osgiInstallerServiceRef = null;
                ServiceReference<ConfigurationAdmin> configAdminServiceRef = 
null;
+               ServiceReference<SlingSettingsService> slingSettingsServiceRef 
= null;
                ServiceRegistration<InstallationListener> 
hookInstallationListenerServiceRegistration = null;
+
                try {
                        switch (context.getPhase()) {
+                       case PREPARE:
+                               if (StringUtils.isBlank(installPathRegex)) {
+                                       throw new IllegalArgumentException(
+                                                       "When using OSGi 
installer install hook for synchronous installation, the package property "
+                                                                       + 
PACKAGE_PROP_INSTALL_PATH_REGEX + " has to be provided.");
+                               }
+                               break;
                        case INSTALLED:
                                ImportOptions options = context.getOptions();
                                logger.setOptions(options);
-                               VaultPackage vaultPackage = 
context.getPackage();
 
                                logger.log(getClass().getSimpleName() + " is 
active in " + vaultPackage.getId());
 
                                List<BundleInPackage> bundleResources = new 
ArrayList<>();
                                List<String> configResourcePaths = new 
ArrayList<>();
                                Archive archive = vaultPackage.getArchive();
-                               collectResources(archive, archive.getRoot(), 
"", bundleResources, configResourcePaths);
+
+                               configAdminServiceRef = 
getBundleContext().getServiceReference(ConfigurationAdmin.class);
+                               ConfigurationAdmin confAdmin = 
(ConfigurationAdmin) getBundleContext()
+                                               
.getService(configAdminServiceRef);
+
+                               slingSettingsServiceRef = 
getBundleContext().getServiceReference(SlingSettingsService.class);
+                               SlingSettingsService slingSettingsService = 
(SlingSettingsService) getBundleContext()
+                                               
.getService(slingSettingsServiceRef);
+                               Set<String> runModes = 
slingSettingsService.getRunModes();
+
+                               collectResources(archive, archive.getRoot(), 
"", bundleResources, configResourcePaths, installPathRegex,
+                                               runModes);
 
                                logger.log("Bundles in package " + 
bundleResources);
 
@@ -114,10 +146,6 @@ public class OsgiInstallerHook implements InstallHook {
                                Set<String> bundleSymbolicNamesToInstall = 
getBundlesToInstall(bundleResources,
                                                bundleVersionsBySymbolicId, 
session, installableResources);
 
-                               configAdminServiceRef = 
getBundleContext().getServiceReference(ConfigurationAdmin.class);
-                               ConfigurationAdmin confAdmin = 
(ConfigurationAdmin) getBundleContext()
-                                               
.getService(configAdminServiceRef);
-
                                Set<String> configPidsToInstall = 
getConfigPidsToInstall(configResourcePaths, session,
                                                installableResources, 
confAdmin);
 
@@ -140,7 +168,7 @@ public class OsgiInstallerHook implements InstallHook {
                                osgiInstaller.updateResources(URL_SCHEME,
                                                
installableResources.toArray(new 
InstallableResource[installableResources.size()]), null);
 
-                               String maxWaitForOsgiInstallerInSecStr = 
vaultPackage.getProperties()
+                               String maxWaitForOsgiInstallerInSecStr = 
packageProperties
                                                
.getProperty(PACKAGE_PROPERTY_MAX_WAIT_IN_SEC);
                                int maxWaitForOsgiInstallerInSec = 
maxWaitForOsgiInstallerInSecStr != null
                                                ? 
Integer.parseInt(maxWaitForOsgiInstallerInSecStr)
@@ -162,7 +190,7 @@ public class OsgiInstallerHook implements InstallHook {
                                break;
                        }
                } catch (Exception e) {
-                       throw new PackageException("Could not execute install 
hook to apply env vars: " + e, e);
+                       throw new PackageException("Could not execute install 
hook to for synchronous installation: " + e, e);
                } finally {
                        if (osgiInstallerServiceRef != null) {
                                
getBundleContext().ungetService(osgiInstallerServiceRef);
@@ -170,6 +198,9 @@ public class OsgiInstallerHook implements InstallHook {
                        if (configAdminServiceRef != null) {
                                
getBundleContext().ungetService(configAdminServiceRef);
                        }
+                       if (slingSettingsServiceRef != null) {
+                               
getBundleContext().ungetService(slingSettingsServiceRef);
+                       }
 
                        if (hookInstallationListenerServiceRegistration != 
null) {
                                
hookInstallationListenerServiceRegistration.unregister();
@@ -248,31 +279,58 @@ public class OsgiInstallerHook implements InstallHook {
        }
 
        private void collectResources(Archive archive, Entry entry, String 
dirPath, List<BundleInPackage> bundleResources,
-                       List<String> configResources) {
+                       List<String> configResources, String installPathRegex, 
Set<String> actualRunmodes) {
                String entryName = entry.getName();
-
-               if (entryName.endsWith(".jar") && dirPath.contains("/install")) 
{
-
-                       try (InputStream entryInputStream = 
archive.getInputSource(entry).getByteStream();
-                                       JarInputStream jarInputStream = new 
JarInputStream(entryInputStream)) {
-                               Manifest manifest = 
jarInputStream.getManifest();
-                               String symbolicName = 
manifest.getMainAttributes().getValue(MANIFEST_BUNDLE_SYMBOLIC_NAME);
-                               String version = 
manifest.getMainAttributes().getValue(MANIFEST_BUNDLE_VERSION);
-                               String bundlePath = 
StringUtils.substringAfter(dirPath + entryName, "/jcr_root");
-                               bundleResources.add(new 
BundleInPackage(bundlePath, symbolicName, version));
-                       } catch (Exception e) {
-                               throw new IllegalStateException(
-                                               "Could not read symbolic name 
and version from manifest of bundle " + entryName);
+               if(entryName.equals("META-INF")) {
+                       return;
+               } 
+
+               String dirPathWithoutJcrRoot = 
StringUtils.substringAfter(dirPath, "/jcr_root");
+               String entryPath = dirPathWithoutJcrRoot + entryName;
+               String dirPathWithoutSlash = 
StringUtils.chomp(dirPathWithoutJcrRoot, "/");
+
+               String dirPathWithoutRunmodes;
+               boolean runmodesMatch;
+               if (dirPathWithoutSlash.contains(DOT)) {
+                       String[] bits = dirPathWithoutSlash.split("\\"+DOT, 2);
+                       dirPathWithoutRunmodes = bits[0];
+                       List<String> runmodesOfResource = 
Arrays.asList(bits[1].split("\\"+DOT));
+                       Set<String> matchingRunmodes = new 
HashSet<String>(runmodesOfResource);
+                       matchingRunmodes.retainAll(actualRunmodes);
+                       LOG.debug("Entry with runmode(s): entryPath={} 
runmodesOfResource={} actualRunmodes={} matchingRunmodes={}", entryPath, 
runmodesOfResource, actualRunmodes, matchingRunmodes);
+                       runmodesMatch = matchingRunmodes.size() == 
runmodesOfResource.size();
+                       if (!runmodesMatch) {
+                               logger.log("Skipping installation of  " + 
entryPath
+                                               + " because the path is not 
matching all actual runmodes " + actualRunmodes);
                        }
+               } else {
+                       dirPathWithoutRunmodes = dirPathWithoutSlash;
+                       runmodesMatch = true;
                }
 
-               if (entryName.endsWith(CONFIG_SUFFIX) && 
dirPath.contains("/config")) {
-                       String configPath = StringUtils.substringAfter(dirPath 
+ entryName, "/jcr_root");
-                       configResources.add(configPath);
+               if (dirPathWithoutRunmodes.matches(installPathRegex) && 
runmodesMatch) {
+
+                       if (entryName.endsWith(CONFIG_SUFFIX)) {
+                               configResources.add(entryPath);
+                       } else if (entryName.endsWith(JAR_SUFFIX)) {
+                               try (InputStream entryInputStream = 
archive.getInputSource(entry).getByteStream();
+                                               JarInputStream jarInputStream = 
new JarInputStream(entryInputStream)) {
+                                       Manifest manifest = 
jarInputStream.getManifest();
+                                       String symbolicName = 
manifest.getMainAttributes().getValue(MANIFEST_BUNDLE_SYMBOLIC_NAME);
+                                       String version = 
manifest.getMainAttributes().getValue(MANIFEST_BUNDLE_VERSION);
+
+                                       bundleResources.add(new 
BundleInPackage(entryPath, symbolicName, version));
+                               } catch (Exception e) {
+                                       throw new IllegalStateException(
+                                                       "Could not read 
symbolic name and version from manifest of bundle " + entryName);
+                               }
+                       }
+
                }
 
                for (Entry child : entry.getChildren()) {
-                       collectResources(archive, child, dirPath + entryName + 
"/", bundleResources, configResources);
+                       collectResources(archive, child, dirPath + entryName + 
"/", bundleResources, configResources,
+                                       installPathRegex, actualRunmodes);
                }
        }
 
@@ -282,7 +340,7 @@ public class OsgiInstallerHook implements InstallHook {
                final InputStream is = 
node.getProperty(JCR_CONTENT_DATA).getStream();
                final Dictionary<String, Object> dict = new Hashtable<String, 
Object>();
                dict.put(InstallableResource.INSTALLATION_HINT, 
node.getParent().getName());
-               return new InstallableResource(path, is, dict, digest, null, 
null);
+               return new InstallableResource(path, is, dict, digest, null, 
PRIORITY_INSTALL_HOOK);
        }
 
        // always get fresh bundle context to avoid "Dynamic class loader has 
already
@@ -294,7 +352,6 @@ public class OsgiInstallerHook implements InstallHook {
                        throw new IllegalStateException(
                                        "The class " + InstallHook.class + " 
was not loaded through a bundle classloader");
                }
-
                BundleContext bundleContext = currentBundle.getBundleContext();
                if (bundleContext == null) {
                        throw new IllegalStateException("Could not get bundle 
context for bundle " + currentBundle);

Reply via email to