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