public void execute()

in src/main/java/org/apache/sling/installer/provider/installhook/OsgiInstallerHook.java [115:237]


    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<SlingSettingsService> slingSettingsServiceRef = null;
        ServiceRegistration<InstallationListener> hookInstallationListenerServiceRegistration = null;

        ServiceReference<InfoProvider> infoProviderServiceRef = 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);

                logger.log(getClass().getSimpleName() + " is active in " + vaultPackage.getId());

                List<BundleInPackage> bundleResources = new ArrayList<>();
                List<String> configResourcePaths = new ArrayList<>();
                Archive archive = vaultPackage.getArchive();

                infoProviderServiceRef = getBundleContext().getServiceReference(InfoProvider.class);
                InfoProvider infoProvider = (InfoProvider) getBundleContext().getService(infoProviderServiceRef);
                InstallationState installationState = infoProvider.getInstallationState();

                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);

                Session session = context.getSession();

                Map<String, InstallableResource> bundlesToInstallByUrl = getBundlesToInstall(bundleResources, session, installationState,
                        packageProperties);
                Map<String, InstallableResource> configsToInstallByUrl = getConfigsToInstall(configResourcePaths, session,
                        installationState, packageProperties);

                if (bundlesToInstallByUrl.isEmpty() && configsToInstallByUrl.isEmpty()) {
                    logger.log("No installable resources that are not installed yet found.");
                    return;
                }

                logger.log("Installing " + bundlesToInstallByUrl.size() + " bundles and "
                        + configsToInstallByUrl.size() + " configs");
                osgiInstallerServiceRef = getBundleContext().getServiceReference(OsgiInstaller.class);
                OsgiInstaller osgiInstaller = getBundleContext().getService(osgiInstallerServiceRef);

                OsgiInstallerListener hookInstallationListener = new OsgiInstallerListener(bundlesToInstallByUrl.keySet(),
                        configsToInstallByUrl.keySet());
                hookInstallationListenerServiceRegistration = getBundleContext()
                        .registerService(InstallationListener.class, hookInstallationListener, null);

                List<InstallableResource> resourcesToUpdate = new ArrayList<>();
                resourcesToUpdate.addAll(bundlesToInstallByUrl.values());
                resourcesToUpdate.addAll(configsToInstallByUrl.values());
                logger.log("Updating resources " + resourcesToUpdate);
                osgiInstaller.updateResources(URL_SCHEME, resourcesToUpdate.toArray(new InstallableResource[resourcesToUpdate.size()]),
                        null);

                int maxWaitForOsgiInstallerInSec = getNumericPackageProperty(packageProperties, PACKAGE_PROPERTY_MAX_WAIT_IN_SEC,
                        DEFAULT_MAX_WAIT_IN_SEC);

                long startTime = System.currentTimeMillis();
                int bundlesLeftToInstall = 0;
                int configsLeftToInstall = 0;
                while ((bundlesLeftToInstall = hookInstallationListener.bundlesLeftToInstall()) > 0
                        || (configsLeftToInstall = hookInstallationListener.configsLeftToInstall()) > 0) {
                    if ((System.currentTimeMillis() - startTime) > maxWaitForOsgiInstallerInSec * 1000) {
                        logger.log("Installable resources " + resourcesToUpdate
                                + " could not be installed even after waiting " + maxWaitForOsgiInstallerInSec + "sec");
                        break;
                    }
                    logger.log("Waiting for " + bundlesLeftToInstall + " bundles / " + configsLeftToInstall + " configs to be installed");
                    Thread.sleep(1000);

                    // the events are not always reliably received, also update listener explicitly with current installation state
                    hookInstallationListener.updateWith(infoProvider.getInstallationState().getInstalledResources());
                }
                if (bundlesLeftToInstall == 0 && configsLeftToInstall == 0) {
                    logger.log("All " + bundlesToInstallByUrl.size() + " bundles / " + configsToInstallByUrl.size()
                            + " configs have been successfully installed in " + (System.currentTimeMillis() - startTime) + "ms");
                }

                int waitForOsgiEventsQuietInSec = getNumericPackageProperty(packageProperties,
                        PACKAGE_PROPERTY_WAIT_FOR_OSGI_EVENTS_QUIET_IN_SEC, DEFAULT_WAIT_FOR_OSGI_EVENTS_QUIET_IN_SEC);
                waitForServiceChanges(waitForOsgiEventsQuietInSec);

                break;
            default:
                break;
            }
        } catch (Exception e) {
            throw new PackageException("Could not execute install hook to for synchronous installation: " + e, e);
        } finally {
            if (osgiInstallerServiceRef != null) {
                getBundleContext().ungetService(osgiInstallerServiceRef);
            }
            if (slingSettingsServiceRef != null) {
                getBundleContext().ungetService(slingSettingsServiceRef);
            }
            if (infoProviderServiceRef != null) {
                getBundleContext().ungetService(infoProviderServiceRef);
            }

            if (hookInstallationListenerServiceRegistration != null) {
                hookInstallationListenerServiceRegistration.unregister();
            }
        }
    }