Author: cziegeler Date: Thu Jan 6 14:11:29 2011 New Revision: 1055884 URL: http://svn.apache.org/viewvc?rev=1055884&view=rev Log: SLING-1920 : Make installers pluggable Convert existing factories to the new service interface and use them as services.
Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/Activator.java sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/RegisteredResourceImpl.java sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/config/ConfigTaskCreator.java sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleTaskCreator.java Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/Activator.java URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/Activator.java?rev=1055884&r1=1055883&r2=1055884&view=diff ============================================================================== --- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/Activator.java (original) +++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/Activator.java Thu Jan 6 14:11:29 2011 @@ -21,6 +21,9 @@ package org.apache.sling.installer.core. import java.util.Hashtable; import org.apache.sling.installer.api.OsgiInstaller; +import org.apache.sling.installer.api.tasks.InstallTaskFactory; +import org.apache.sling.installer.core.impl.config.ConfigTaskCreator; +import org.apache.sling.installer.core.impl.tasks.BundleTaskCreator; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; @@ -38,10 +41,19 @@ public class Activator implements Bundle private OsgiInstallerImpl osgiControllerService; private ServiceRegistration osgiControllerServiceReg; + private BundleTaskCreator bundleTaskFactory; + private ServiceRegistration bundleTaskFactoryReg; + + private ConfigTaskCreator configTaskFactory; + private ServiceRegistration configTaskFactoryReg; + /** * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ public void start(final BundleContext context) throws Exception { + // register install task factories + this.registerFactories(context); + // register osgi installer service final Hashtable<String, String> props = new Hashtable<String, String>(); props.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Install Controller Service"); @@ -59,7 +71,7 @@ public class Activator implements Bundle /** * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) */ - public void stop(BundleContext context) { + public void stop(final BundleContext context) { // stop osgi installer service if ( this.osgiControllerService != null ) { this.osgiControllerService.deactivate(); @@ -70,5 +82,43 @@ public class Activator implements Bundle this.osgiControllerServiceReg.unregister(); this.osgiControllerServiceReg = null; } + if ( this.bundleTaskFactoryReg != null ) { + this.bundleTaskFactoryReg.unregister(); + this.bundleTaskFactoryReg = null; + } + if ( this.bundleTaskFactory != null ) { + this.bundleTaskFactory.deactivate(); + this.bundleTaskFactory = null; + } + if ( this.configTaskFactoryReg != null ) { + this.configTaskFactoryReg.unregister(); + this.configTaskFactoryReg = null; + } + if ( this.configTaskFactory != null ) { + this.configTaskFactory.deactivate(); + this.configTaskFactory = null; + } + } + + private void registerFactories(final BundleContext context) { + final String [] serviceInterfaces = { + InstallTaskFactory.class.getName() + }; + + Hashtable<String, String> props = new Hashtable<String, String>(); + props.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Bundle Install Task Factory"); + props.put(Constants.SERVICE_VENDOR, VENDOR); + + this.bundleTaskFactory = new BundleTaskCreator(context); + this.bundleTaskFactoryReg = context.registerService(serviceInterfaces, + bundleTaskFactory, props); + + props = new Hashtable<String, String>(); + props.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Configuration Install Task Factory"); + props.put(Constants.SERVICE_VENDOR, VENDOR); + + this.configTaskFactory = new ConfigTaskCreator(context); + this.configTaskFactoryReg = context.registerService(serviceInterfaces, + configTaskFactory, props); } } 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=1055884&r1=1055883&r2=1055884&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 Thu Jan 6 14:11:29 2011 @@ -35,16 +35,17 @@ import java.util.TreeSet; import org.apache.sling.installer.api.InstallableResource; import org.apache.sling.installer.api.OsgiInstaller; -import org.apache.sling.installer.api.tasks.InstallationContext; import org.apache.sling.installer.api.tasks.InstallTask; +import org.apache.sling.installer.api.tasks.InstallTaskFactory; +import org.apache.sling.installer.api.tasks.InstallationContext; import org.apache.sling.installer.api.tasks.RegisteredResource; -import org.apache.sling.installer.core.impl.config.ConfigTaskCreator; -import org.apache.sling.installer.core.impl.tasks.BundleTaskCreator; +import org.apache.sling.installer.api.tasks.RegisteredResourceGroup; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; import org.osgi.framework.BundleListener; import org.osgi.framework.FrameworkEvent; import org.osgi.framework.FrameworkListener; +import org.osgi.util.tracker.ServiceTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -90,16 +91,16 @@ public class OsgiInstallerImpl private volatile boolean retriesScheduled; - - private BundleTaskCreator bundleTaskCreator; - private ConfigTaskCreator configTaskCreator; - private final FileUtil fileUtil; + private final ServiceTracker factoryTracker; + /** Constructor */ public OsgiInstallerImpl(final BundleContext ctx) { this.ctx = ctx; this.fileUtil = new FileUtil(ctx); + this.factoryTracker = new ServiceTracker(ctx, InstallTaskFactory.class.getName(), null); + this.factoryTracker.open(); } /** @@ -107,8 +108,7 @@ public class OsgiInstallerImpl */ public void deactivate() { this.active = false; - this.configTaskCreator.deactivate(); - this.bundleTaskCreator.deactivate(); + this.factoryTracker.close(); ctx.removeBundleListener(this); ctx.removeFrameworkListener(this); // wake up sleeping thread @@ -132,8 +132,6 @@ public class OsgiInstallerImpl // listen to framework and bundle events this.ctx.addFrameworkListener(this); this.ctx.addBundleListener(this); - this.configTaskCreator = new ConfigTaskCreator(ctx); - this.bundleTaskCreator = new BundleTaskCreator(ctx); setName(getClass().getSimpleName()); final File f = this.fileUtil.getDataFile("RegisteredResourceList.ser"); persistentList = new PersistentResourceList(f); @@ -423,39 +421,44 @@ public class OsgiInstallerImpl } // Walk the list of entities, and create appropriate OSGi tasks for each group - for(final String entityId : this.persistentList.getEntityIds()) { - final EntityResourceList group = this.persistentList.getEntityResourceList(entityId); - // Check the first resource in each group - final RegisteredResource first = group.getActiveResource(); - if ( first != null ) { - RegisteredResource toActivate = null; - switch ( first.getState() ) { - case UNINSTALL : toActivate = first; - break; - case INSTALL : toActivate = first; - break; - } + final Object[] services = this.factoryTracker.getServices(); + if ( services != null && services.length > 0 ) { + for(final String entityId : this.persistentList.getEntityIds()) { + final EntityResourceList group = this.persistentList.getEntityResourceList(entityId); + // Check the first resource in each group + final RegisteredResource toActivate = group.getActiveResource(); if ( toActivate != null ) { - final String rt = toActivate.getType(); - final InstallTask task; - if ( InstallableResource.TYPE_BUNDLE.equals(rt) ) { - task = bundleTaskCreator.createTask(group); - } else if ( InstallableResource.TYPE_CONFIG.equals(rt) ) { - task = configTaskCreator.createTask(group); - } else { - task = null; - } + final InstallTask task = getTask(services, group); if ( task != null ) { tasks.add(task); } - } + } } } return tasks; } /** + * Get the task for the resource. + */ + private InstallTask getTask(final Object[] services, + final RegisteredResourceGroup rrg) { + InstallTask result = null; + + for(int i=0; i<services.length; i++) { + if ( services[i] instanceof InstallTaskFactory ) { + final InstallTaskFactory factory = (InstallTaskFactory)services[i]; + result = factory.createTask(rrg); + if ( result != null ) { + break; + } + } + } + return result; + } + + /** * Execute all tasks */ private void executeTasks(final SortedSet<InstallTask> tasks) { Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/RegisteredResourceImpl.java URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/RegisteredResourceImpl.java?rev=1055884&r1=1055883&r2=1055884&view=diff ============================================================================== --- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/RegisteredResourceImpl.java (original) +++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/RegisteredResourceImpl.java Thu Jan 6 14:11:29 2011 @@ -159,9 +159,6 @@ public class RegisteredResourceImpl // unknown resource type throw new IOException("Unknown resource type for resource " + input.getId()); } - if ( !resourceType.equals(InstallableResource.TYPE_CONFIG) && !resourceType.equals(InstallableResource.TYPE_BUNDLE) ) { - throw new IOException("Unsupported resource type " + resourceType + " for resource " + input.getId()); - } if ( is != null && resourceType.equals(InstallableResource.TYPE_CONFIG ) ) { dict = readDictionary(is, getExtension(input.getId())); if ( dict == null ) { @@ -255,7 +252,21 @@ public class RegisteredResourceImpl } } else { - throw new IOException("Unknown type " + resourceType); + // we just copy the input stream + try { + this.dataFile = fileUtil.createNewDataFile(getType()); + copyToLocalStorage(is); + this.digest = (digest != null && digest.length() > 0 ? digest : id + ":" + computeDigest(this.dataFile)); + // remove path + String pid = id; + final int slashPos = pid.lastIndexOf('/'); + if ( slashPos != -1 ) { + pid = pid.substring(slashPos + 1); + } + entity = resourceType + ':' + pid; + } finally { + is.close(); + } } } Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/config/ConfigTaskCreator.java URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/config/ConfigTaskCreator.java?rev=1055884&r1=1055883&r2=1055884&view=diff ============================================================================== --- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/config/ConfigTaskCreator.java (original) +++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/config/ConfigTaskCreator.java Thu Jan 6 14:11:29 2011 @@ -18,7 +18,9 @@ */ package org.apache.sling.installer.core.impl.config; +import org.apache.sling.installer.api.InstallableResource; import org.apache.sling.installer.api.tasks.InstallTask; +import org.apache.sling.installer.api.tasks.InstallTaskFactory; import org.apache.sling.installer.api.tasks.RegisteredResource; import org.apache.sling.installer.api.tasks.RegisteredResourceGroup; import org.osgi.framework.BundleContext; @@ -28,7 +30,7 @@ import org.osgi.util.tracker.ServiceTrac /** * Task creator for configurations. */ -public class ConfigTaskCreator { +public class ConfigTaskCreator implements InstallTaskFactory { public static final String ALIAS_KEY = "org.apache.sling.installer.osgi.factoryaliaspid"; public static final String CONFIG_PATH_KEY = "org.apache.sling.installer.osgi.path"; @@ -57,17 +59,23 @@ public class ConfigTaskCreator { /** * Create a task to install or uninstall a configuration. + * + * @see org.apache.sling.installer.api.tasks.InstallTaskFactory#createTask(org.apache.sling.installer.api.tasks.RegisteredResourceGroup) */ - public InstallTask createTask(final RegisteredResourceGroup toActivate) { + public InstallTask createTask(final RegisteredResourceGroup group) { + final RegisteredResource toActivate = group.getActiveResource(); + if ( !toActivate.getType().equals(InstallableResource.TYPE_CONFIG) ) { + return null; + } // if there is no config admin, just return if ( this.configAdminServiceTracker.getService() == null ) { return null; } final InstallTask result; - if (toActivate.getActiveResource().getState() == RegisteredResource.State.UNINSTALL) { - result = new ConfigRemoveTask(toActivate, this.configAdminServiceTracker); + if (toActivate.getState() == RegisteredResource.State.UNINSTALL) { + result = new ConfigRemoveTask(group, this.configAdminServiceTracker); } else { - result = new ConfigInstallTask(toActivate, this.configAdminServiceTracker); + result = new ConfigInstallTask(group, this.configAdminServiceTracker); } return result; } Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleTaskCreator.java URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleTaskCreator.java?rev=1055884&r1=1055883&r2=1055884&view=diff ============================================================================== --- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleTaskCreator.java (original) +++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleTaskCreator.java Thu Jan 6 14:11:29 2011 @@ -18,7 +18,9 @@ */ package org.apache.sling.installer.core.impl.tasks; +import org.apache.sling.installer.api.InstallableResource; import org.apache.sling.installer.api.tasks.InstallTask; +import org.apache.sling.installer.api.tasks.InstallTaskFactory; import org.apache.sling.installer.api.tasks.RegisteredResource; import org.apache.sling.installer.api.tasks.RegisteredResourceGroup; import org.osgi.framework.Bundle; @@ -34,7 +36,7 @@ import org.slf4j.LoggerFactory; /** * Task creator for bundles */ -public class BundleTaskCreator { +public class BundleTaskCreator implements InstallTaskFactory { /** The logger */ private final Logger logger = LoggerFactory.getLogger(this.getClass()); @@ -115,9 +117,14 @@ public class BundleTaskCreator { /** * Create a bundle task - install, update or remove + * + * @see org.apache.sling.installer.api.tasks.InstallTaskFactory#createTask(org.apache.sling.installer.api.tasks.RegisteredResourceGroup) */ public InstallTask createTask(final RegisteredResourceGroup resourceList) { final RegisteredResource toActivate = resourceList.getActiveResource(); + if ( !toActivate.getType().equals(InstallableResource.TYPE_BUNDLE) ) { + return null; + } final InstallTask result; final String symbolicName = (String)toActivate.getAttributes().get(Constants.BUNDLE_SYMBOLICNAME);