Author: cziegeler
Date: Fri Jan 21 12:57:17 2011
New Revision: 1061795

URL: http://svn.apache.org/viewvc?rev=1061795&view=rev
Log:
SLING-1943 : Sort services (transformer and factories) by service ranking 
before invoking

Added:
    
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/SortingServiceTracker.java
   (with props)
Modified:
    
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java

Modified: 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java?rev=1061795&r1=1061794&r2=1061795&view=diff
==============================================================================
--- 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java
 (original)
+++ 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java
 Fri Jan 21 12:57:17 2011
@@ -48,9 +48,6 @@ import org.osgi.framework.BundleEvent;
 import org.osgi.framework.BundleListener;
 import org.osgi.framework.FrameworkEvent;
 import org.osgi.framework.FrameworkListener;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -65,7 +62,7 @@ import org.slf4j.LoggerFactory;
  */
 public class OsgiInstallerImpl
     extends Thread
-    implements BundleListener, FrameworkListener, OsgiInstaller, 
ServiceTrackerCustomizer {
+    implements BundleListener, FrameworkListener, OsgiInstaller {
 
     /** The logger */
     private final Logger logger =  LoggerFactory.getLogger(this.getClass());
@@ -95,10 +92,10 @@ public class OsgiInstallerImpl
     private PersistentResourceList persistentList;
 
     /** A tracker for the factories. */
-    private ServiceTracker factoryTracker;
+    private SortingServiceTracker<InstallTaskFactory> factoryTracker;
 
     /** A tracker for the transformers. */
-    private ServiceTracker transformerTracker;
+    private SortingServiceTracker<ResourceTransformer> transformerTracker;
 
     /** New resources lock. */
     private final Object resourcesLock = new Object();
@@ -146,9 +143,9 @@ public class OsgiInstallerImpl
      */
     private void init() {
         // start service trackers
-        this.factoryTracker = new ServiceTracker(ctx, 
InstallTaskFactory.class.getName(), this);
+        this.factoryTracker = new 
SortingServiceTracker<InstallTaskFactory>(ctx, 
InstallTaskFactory.class.getName(), this);
         this.factoryTracker.open();
-        this.transformerTracker = new ServiceTracker(ctx, 
ResourceTransformer.class.getName(), this);
+        this.transformerTracker = new 
SortingServiceTracker<ResourceTransformer>(ctx, 
ResourceTransformer.class.getName(), this);
         this.transformerTracker.open();
 
         // listen to framework and bundle events
@@ -449,7 +446,7 @@ public class OsgiInstallerImpl
         }
 
         // Walk the list of entities, and create appropriate OSGi tasks for 
each group
-        final Object[] services = this.factoryTracker.getServices();
+        final InstallTaskFactory[] services = 
this.factoryTracker.getSortedServices();
         if ( services != null && services.length > 0 ) {
             for(final String entityId : this.persistentList.getEntityIds()) {
                 final EntityResourceList group = 
this.persistentList.getEntityResourceList(entityId);
@@ -470,13 +467,13 @@ public class OsgiInstallerImpl
     /**
      * Get the task for the resource.
      */
-    private InstallTask getTask(final Object[] services,
+    private InstallTask getTask(final InstallTaskFactory[] services,
             final TaskResourceGroup rrg) {
         InstallTask result = null;
 
         for(int i=0; i<services.length; i++) {
-            if ( services[i] instanceof InstallTaskFactory ) {
-                final InstallTaskFactory factory = 
(InstallTaskFactory)services[i];
+            final InstallTaskFactory factory = services[i];
+            if ( factory != null ) {
                 result = factory.createTask(rrg);
                 if ( result != null ) {
                     break;
@@ -545,7 +542,7 @@ public class OsgiInstallerImpl
     private void transformResources() {
         boolean changed = false;
 
-        final Object[] services = this.transformerTracker.getServices();
+        final ResourceTransformer[] services = 
this.transformerTracker.getSortedServices();
 
         if ( services != null && services.length > 0 ) {
             // Walk the list of unknown resources and invoke all transformers
@@ -555,8 +552,8 @@ public class OsgiInstallerImpl
             while ( index < unknownList.size() ) {
                 final RegisteredResource resource = unknownList.get(index);
                 for(int i=0; i<services.length; i++) {
-                    if ( services[i] instanceof ResourceTransformer ) {
-                        final ResourceTransformer transformer = 
(ResourceTransformer)services[i];
+                    final ResourceTransformer transformer = services[i];
+                    if ( transformer != null ) {
 
                         try {
                             final TransformationResult[] result = 
transformer.transform(resource);
@@ -632,29 +629,9 @@ public class OsgiInstallerImpl
     }
 
     /**
-     * @see 
org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference,
 java.lang.Object)
+     * Wake up the run cycle.
      */
-    public void removedService(ServiceReference reference, Object service) {
-        ctx.ungetService(reference);
-    }
-
-    /**
-     * @see 
org.osgi.util.tracker.ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference,
 java.lang.Object)
-     */
-    public void modifiedService(ServiceReference reference, Object service) {
-        // do nothing
-    }
-
-    /**
-     * @see 
org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
-     */
-    public Object addingService(ServiceReference reference) {
-        // new factory has been added, wake up main thread
-        this.wakeUp();
-        return ctx.getService(reference);
-    }
-
-    private void wakeUp() {
+    public void wakeUp() {
         synchronized (this.resourcesLock) {
             this.resourcesLock.notify();
         }

Added: 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/SortingServiceTracker.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/SortingServiceTracker.java?rev=1061795&view=auto
==============================================================================
--- 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/SortingServiceTracker.java
 (added)
+++ 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/SortingServiceTracker.java
 Fri Jan 21 12:57:17 2011
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.sling.installer.core.impl;
+
+import java.util.Arrays;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * Implementation providing a sorted list of services
+ * by service ranking.
+ */
+public class SortingServiceTracker<T>
+    extends ServiceTracker  {
+
+    private final OsgiInstallerImpl listener;
+
+    private int lastCount = -1;
+
+    private T[] sortedServiceCache;
+
+    /**
+     * Constructor
+     */
+    public SortingServiceTracker(final BundleContext context,
+            final String clazz,
+            final OsgiInstallerImpl listener) {
+        super(context, clazz, null);
+        this.listener = listener;
+    }
+
+    /**
+     * @see 
org.osgi.util.tracker.ServiceTracker#removedService(org.osgi.framework.ServiceReference,
 java.lang.Object)
+     */
+    @Override
+    public void removedService(ServiceReference reference, Object service) {
+        this.sortedServiceCache = null;
+        this.context.ungetService(reference);
+    }
+
+    /**
+     * @see 
org.osgi.util.tracker.ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference,
 java.lang.Object)
+     */
+    @Override
+    public void modifiedService(ServiceReference reference, Object service) {
+        this.sortedServiceCache = null;
+    }
+
+    /**
+     * @see 
org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     */
+    @Override
+    public Object addingService(ServiceReference reference) {
+        this.sortedServiceCache = null;
+        // new factory has been added, wake up main thread
+        this.listener.wakeUp();
+        return context.getService(reference);
+    }
+
+    /**
+     * Return a sorted array of the services.
+     */
+    @SuppressWarnings("unchecked")
+    public T[] getSortedServices() {
+        if ( this.sortedServiceCache == null || this.lastCount < 
this.getTrackingCount() ) {
+            this.lastCount = this.getTrackingCount();
+            final ServiceReference[] references = this.getServiceReferences();
+            if ( references == null || references.length == 0 ) {
+                this.sortedServiceCache = (T[])new Object[0];
+            } else {
+                Arrays.sort(references);
+                this.sortedServiceCache = (T[])new Object[references.length];
+                for(int i=0;i<references.length;i++) {
+                    this.sortedServiceCache[i] = 
(T)this.getService(references[references.length - 1 - i]);
+                }
+            }
+        }
+        return this.sortedServiceCache;
+    }
+}

Propchange: 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/SortingServiceTracker.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/SortingServiceTracker.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/SortingServiceTracker.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain


Reply via email to