You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2016/11/09 13:20:38 UTC

svn commit: r1768960 - /sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java

Author: cziegeler
Date: Wed Nov  9 13:20:38 2016
New Revision: 1768960

URL: http://svn.apache.org/viewvc?rev=1768960&view=rev
Log:
SLING-6263 : Dependency problem between RepositoryInitializer and AbstractSlingRepositoryManager

Modified:
    sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java

Modified: sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java?rev=1768960&r1=1768959&r2=1768960&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java (original)
+++ sling/trunk/bundles/jcr/base/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java Wed Nov  9 13:20:38 2016
@@ -34,6 +34,7 @@ import org.osgi.framework.ServiceFactory
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -96,10 +97,12 @@ public abstract class AbstractSlingRepos
 
     private volatile boolean disableLoginAdministrative;
 
-    private volatile ServiceTracker repoInitializerTracker;
+    private volatile ServiceTracker<SlingRepositoryInitializer, SlingRepositoryInitializerInfo> repoInitializerTracker;
 
     private volatile Loader loader;
 
+    private final Object repoInitLock = new Object();
+
     /**
      * Returns the default workspace, which may be <code>null</code> meaning to
      * use the repository provided default workspace.
@@ -315,7 +318,42 @@ public abstract class AbstractSlingRepos
         this.defaultWorkspace = defaultWorkspace;
         this.disableLoginAdministrative = disableLoginAdministrative;
 
-        this.repoInitializerTracker = new ServiceTracker(bundleContext, SlingRepositoryInitializer.class.getName(), null);
+        this.repoInitializerTracker = new ServiceTracker<SlingRepositoryInitializer, SlingRepositoryInitializerInfo>(bundleContext, SlingRepositoryInitializer.class,
+                new ServiceTrackerCustomizer<SlingRepositoryInitializer, SlingRepositoryInitializerInfo>() {
+
+                    @Override
+                    public SlingRepositoryInitializerInfo addingService(final ServiceReference<SlingRepositoryInitializer> reference) {
+                        final SlingRepositoryInitializer service = bundleContext.getService(reference);
+                        if ( service != null ) {
+                            final SlingRepositoryInitializerInfo info = new SlingRepositoryInitializerInfo(service, reference);
+                            synchronized ( repoInitLock ) {
+                                if ( masterSlingRepository != null ) {
+                                    log.debug("Executing {}", info.initializer);
+                                    try {
+                                        info.initializer.processRepository(masterSlingRepository);
+                                    } catch (final Exception e) {
+                                        log.error("Exception in a SlingRepositoryInitializer: " + info.initializer, e);
+                                    }
+                                }
+                            }
+                            return info;
+                        }
+                        return null;
+                    }
+
+                    @Override
+                    public void modifiedService(final ServiceReference<SlingRepositoryInitializer> reference,
+                            final SlingRepositoryInitializerInfo service) {
+                        // nothing to do
+                    }
+
+                    @Override
+                    public void removedService(final ServiceReference<SlingRepositoryInitializer> reference,
+                            final SlingRepositoryInitializerInfo service) {
+                        bundleContext.ungetService(reference);
+                    }
+
+        });
         this.repoInitializerTracker.open();
 
         try {
@@ -326,29 +364,31 @@ public abstract class AbstractSlingRepos
                 // ensure we really have the repository
                 log.debug("start: got a Repository");
                 this.repository = newRepo;
-                this.masterSlingRepository = this.create(this.bundleContext.getBundle());
+                synchronized ( this.repoInitLock ) {
+                    this.masterSlingRepository = this.create(this.bundleContext.getBundle());
 
-                log.debug("start: setting up Loader");
-                this.loader = new Loader(this.masterSlingRepository, this.bundleContext);
+                    log.debug("start: setting up Loader");
+                    this.loader = new Loader(this.masterSlingRepository, this.bundleContext);
 
-                log.debug("start: calling SlingRepositoryInitializer");
-                Throwable t = null;
-                try {
-                    executeRepositoryInitializers(this.masterSlingRepository);
-                } catch(Exception e) {
-                    t = e;
-                } catch(Error e) {
-                    t = e;
-                }
-                if(t != null) {
-                    log.error("Exception in a SlingRepositoryInitializer, SlingRepository service registration aborted", t);
-                    return false;
-                }
+                    log.debug("start: calling SlingRepositoryInitializer");
+                    Throwable t = null;
+                    try {
+                        executeRepositoryInitializers(this.masterSlingRepository);
+                    } catch(Exception e) {
+                        t = e;
+                    } catch(Error e) {
+                        t = e;
+                    }
+                    if(t != null) {
+                        log.error("Exception in a SlingRepositoryInitializer, SlingRepository service registration aborted", t);
+                        return false;
+                    }
 
-                log.debug("start: calling registerService()");
-                this.repositoryService = registerService();
+                    log.debug("start: calling registerService()");
+                    this.repositoryService = registerService();
 
-                log.debug("start: registerService() successful, registration=" + repositoryService);
+                    log.debug("start: registerService() successful, registration=" + repositoryService);
+                }
                 return true;
             }
         } catch (Throwable t) {
@@ -363,21 +403,16 @@ public abstract class AbstractSlingRepos
         return false;
     }
 
-    private void executeRepositoryInitializers(SlingRepository repo) throws Exception {
-        final ServiceReference [] refs = repoInitializerTracker.getServiceReferences();
-        if(refs == null || refs.length == 0) {
+    private void executeRepositoryInitializers(final SlingRepository repo) throws Exception {
+        final SlingRepositoryInitializerInfo [] infos = repoInitializerTracker.getServices(new SlingRepositoryInitializerInfo[0]);
+        if (infos == null || infos.length == 0) {
             log.debug("No SlingRepositoryInitializer services found");
             return;
         }
-        Arrays.sort(refs);
-        for(ServiceReference ref : refs) {
-            final SlingRepositoryInitializer sri = (SlingRepositoryInitializer)bundleContext.getService(ref);
-            log.debug("Executing {}", sri);
-            try {
-                sri.processRepository(repo);
-            } finally {
-                bundleContext.ungetService(ref);
-            }
+        Arrays.sort(infos);
+        for(final SlingRepositoryInitializerInfo info : infos) {
+            log.debug("Executing {}", info.initializer);
+            info.initializer.processRepository(repo);
         }
     }
 
@@ -433,4 +468,20 @@ public abstract class AbstractSlingRepos
         this.defaultWorkspace = null;
         this.bundleContext = null;
     }
+
+    public static final class SlingRepositoryInitializerInfo implements Comparable<SlingRepositoryInitializerInfo> {
+
+        public final SlingRepositoryInitializer initializer;
+        public final ServiceReference<SlingRepositoryInitializer> ref;
+
+        public SlingRepositoryInitializerInfo(final SlingRepositoryInitializer init, ServiceReference<SlingRepositoryInitializer> ref) {
+            this.initializer = init;
+            this.ref = ref;
+        }
+
+        @Override
+        public int compareTo(SlingRepositoryInitializerInfo o) {
+            return ref.compareTo(o.ref);
+        }
+    }
 }