You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:42:58 UTC
[sling-org-apache-sling-installer-factory-subsystems] 01/10:
Initial subsystem support for the OSGi installer
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to annotated tag org.apache.sling.installer.factory.subsystems-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-factory-subsystems.git
commit aabcbfb8a829a64bdaed163f655a0a658fb8d244
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Aug 6 16:20:32 2014 +0000
Initial subsystem support for the OSGi installer
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/installer/factories/subsystems@1616266 13f79535-47bb-0310-9956-ffa450edef68
---
pom.xml | 86 ++++++
.../factories/subsystems/impl/Activator.java | 100 +++++++
.../subsystems/impl/InstallSubsystemTask.java | 60 ++++
.../subsystems/impl/SubsystemInstaller.java | 304 +++++++++++++++++++++
.../subsystems/impl/UninstallSubsystemTask.java | 73 +++++
.../subsystems/impl/UpdateSubsystemTask.java | 77 ++++++
6 files changed, 700 insertions(+)
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..d3f0918
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,86 @@
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>sling</artifactId>
+ <version>18</version>
+ <relativePath>../../../parent/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>org.apache.sling.installer.factory.subsystems</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+
+ <name>Apache Sling Subsystems Installer</name>
+ <description>
+ Provides support for subsystems to the Apache Sling OSGi installer
+ </description>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/installer/factories/subsystems</connection>
+ <developerConnection> scm:svn:https://svn.apache.org/repos/asf/sling/trunk/installer/factories/subsystems</developerConnection>
+ <url>http://svn.apache.org/viewvc/sling/trunk/installer/factories/subsystems/</url>
+ </scm>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Activator>
+ org.apache.sling.installer.factories.subsystems.impl.Activator
+ </Bundle-Activator>
+ <Private-Package>
+ org.apache.sling.installer.factories.subsystems.impl.*
+ </Private-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>5.0.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>5.0.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.installer.api</artifactId>
+ <version>1.0.0</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/src/main/java/org/apache/sling/installer/factories/subsystems/impl/Activator.java b/src/main/java/org/apache/sling/installer/factories/subsystems/impl/Activator.java
new file mode 100644
index 0000000..2a4e173
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/factories/subsystems/impl/Activator.java
@@ -0,0 +1,100 @@
+/*
+ * 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.factories.subsystems.impl;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.sling.installer.api.tasks.InstallTaskFactory;
+import org.apache.sling.installer.api.tasks.ResourceTransformer;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.subsystem.Subsystem;
+import org.osgi.service.subsystem.SubsystemConstants;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+public class Activator implements BundleActivator {
+
+ /** The service tracker for the root subsystem */
+ private ServiceTracker<Subsystem, Subsystem> rootSubsystemTracker;
+
+ /** The service registration for the installer service. */
+ private ServiceRegistration<?> serviceReg;
+
+ /**
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(final BundleContext context) throws Exception {
+ this.rootSubsystemTracker = new ServiceTracker<Subsystem, Subsystem>(context,
+ "&(" + Constants.OBJECTCLASS + "=" + Subsystem.class.getName() + ")" +
+ "(" + SubsystemConstants.SUBSYSTEM_ID_PROPERTY + "=0)",
+
+ new ServiceTrackerCustomizer<Subsystem, Subsystem>() {
+
+ public Subsystem addingService(final ServiceReference<Subsystem> reference) {
+ final Subsystem service = context.getService(reference);
+ if ( service != null ) {
+ registerInstaller(context, service);
+ }
+ return service;
+ }
+
+ public void modifiedService(final ServiceReference<Subsystem> reference, final Subsystem service) {
+ // nothing to do
+ }
+
+ public void removedService(final ServiceReference<Subsystem> reference, final Subsystem service) {
+ unregisterInstaller();
+ }
+
+ });
+ this.rootSubsystemTracker.open();
+ }
+
+ /**
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(final BundleContext context) throws Exception {
+ if ( this.rootSubsystemTracker != null ) {
+ this.rootSubsystemTracker.close();
+ this.rootSubsystemTracker = null;
+ }
+ this.unregisterInstaller();
+ }
+
+ private void registerInstaller(final BundleContext context, final Subsystem rootSubsystem) {
+ final Dictionary<String, Object> props = new Hashtable<String, Object>();
+ props.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Installer Support for Subsystems");
+ props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+ this.serviceReg = context.registerService(
+ new String[] {ResourceTransformer.class.getName(), InstallTaskFactory.class.getName()},
+ new SubsystemInstaller(rootSubsystem, context), props);
+ }
+
+ private void unregisterInstaller() {
+ if ( serviceReg != null ) {
+ serviceReg.unregister();
+ serviceReg = null;
+ }
+ }
+}
diff --git a/src/main/java/org/apache/sling/installer/factories/subsystems/impl/InstallSubsystemTask.java b/src/main/java/org/apache/sling/installer/factories/subsystems/impl/InstallSubsystemTask.java
new file mode 100644
index 0000000..3f1e10f
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/factories/subsystems/impl/InstallSubsystemTask.java
@@ -0,0 +1,60 @@
+/*
+ * 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.factories.subsystems.impl;
+
+import java.io.IOException;
+
+import org.apache.sling.installer.api.tasks.ChangeStateTask;
+import org.apache.sling.installer.api.tasks.InstallTask;
+import org.apache.sling.installer.api.tasks.InstallationContext;
+import org.apache.sling.installer.api.tasks.ResourceState;
+import org.apache.sling.installer.api.tasks.TaskResource;
+import org.apache.sling.installer.api.tasks.TaskResourceGroup;
+import org.osgi.service.subsystem.Subsystem;
+
+public class InstallSubsystemTask extends InstallTask {
+
+ private static final String INSTALL_ORDER = "53-";
+
+ private final Subsystem rootSubsystem;
+
+ public InstallSubsystemTask(final TaskResourceGroup grp, final Subsystem rootSubsystem) {
+ super(grp);
+ this.rootSubsystem = rootSubsystem;
+ }
+
+ @Override
+ public void execute(final InstallationContext ctx) {
+ final TaskResource tr = this.getResource();
+ ctx.log("Installing new subsystem from {}", tr);
+
+ try {
+ this.rootSubsystem.install(tr.getURL(), tr.getInputStream());
+ ctx.addTaskToCurrentCycle(new ChangeStateTask(this.getResourceGroup(), ResourceState.INSTALLED));
+ } catch (final IOException e) {
+ ctx.log("Unable to install subsystem {} : {}", tr, e);
+ ctx.addTaskToCurrentCycle(new ChangeStateTask(this.getResourceGroup(), ResourceState.IGNORED));
+ }
+ }
+
+ @Override
+ public String getSortKey() {
+ return INSTALL_ORDER + getResource().getURL();
+ }
+}
diff --git a/src/main/java/org/apache/sling/installer/factories/subsystems/impl/SubsystemInstaller.java b/src/main/java/org/apache/sling/installer/factories/subsystems/impl/SubsystemInstaller.java
new file mode 100644
index 0000000..2b4b3c5
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/factories/subsystems/impl/SubsystemInstaller.java
@@ -0,0 +1,304 @@
+/*
+ * 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.factories.subsystems.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import org.apache.sling.installer.api.InstallableResource;
+import org.apache.sling.installer.api.tasks.ChangeStateTask;
+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.ResourceState;
+import org.apache.sling.installer.api.tasks.ResourceTransformer;
+import org.apache.sling.installer.api.tasks.TaskResource;
+import org.apache.sling.installer.api.tasks.TaskResourceGroup;
+import org.apache.sling.installer.api.tasks.TransformationResult;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.service.subsystem.Subsystem;
+import org.osgi.service.subsystem.SubsystemConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is an extension for the OSGi installer
+ * It listens for files ending with ".esa" and a proper manifest. Though subsystems does
+ * not require a complete manifest, the installer supports only subsystems with the
+ * basic info.
+ */
+public class SubsystemInstaller
+ implements ResourceTransformer, InstallTaskFactory {
+
+ private static final String TYPE_SUBSYSTEM = "esa";
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private final Subsystem rootSubsystem;
+
+ private final BundleContext bundleContext;
+
+ public SubsystemInstaller(final Subsystem root, final BundleContext bundleContext) {
+ this.rootSubsystem = root;
+ this.bundleContext = bundleContext;
+ }
+
+ /**
+ * @see org.apache.sling.installer.api.tasks.ResourceTransformer#transform(org.apache.sling.installer.api.tasks.RegisteredResource)
+ */
+ public TransformationResult[] transform(final RegisteredResource resource) {
+ if ( resource.getType().equals(InstallableResource.TYPE_FILE) ) {
+ if ( resource.getURL().endsWith("." + TYPE_SUBSYSTEM) ) {
+ logger.info("Found potential subsystem resource {}", resource);
+ final SubsystemInfo headers = readSubsystemHeaders(resource);
+ if ( headers != null ) {
+ // check the version for validity
+ boolean validVersion = true;
+ try {
+ new Version(headers.version);
+ } catch (final IllegalArgumentException iae) {
+ logger.info("Rejecting subsystem {} from {} due to invalid version information: {}.",
+ new Object[] {headers.symbolicName, resource, headers.version});
+ validVersion = false;
+ }
+ if ( validVersion ) {
+ final Map<String, Object> attr = new HashMap<String, Object>();
+ attr.put(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME, headers.symbolicName);
+ attr.put(SubsystemConstants.SUBSYSTEM_VERSION, headers.version);
+
+ final TransformationResult tr = new TransformationResult();
+ tr.setId(headers.symbolicName);
+ tr.setResourceType(TYPE_SUBSYSTEM);
+ tr.setAttributes(attr);
+ tr.setVersion(new Version(headers.version));
+
+ return new TransformationResult[] {tr};
+ }
+
+ } else {
+ logger.info("Subsystem resource does not have required headers.");
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Check that the required attributes are available.
+ * This is just a sanity check
+ */
+ private SubsystemInfo checkResource(final TaskResourceGroup toActivate) {
+ final TaskResource rsrc = toActivate.getActiveResource();
+
+ SubsystemInfo result = null;
+ final String symbolicName = (String) rsrc.getAttribute(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME);
+ if ( symbolicName == null ) {
+ logger.error("Subsystem resource is missing symbolic name {}", rsrc);
+ } else {
+ final String version = (String)rsrc.getAttribute(SubsystemConstants.SUBSYSTEM_VERSION);
+ if ( version == null ) {
+ logger.error("Subsystem resource is missing version {}", rsrc);
+ } else {
+ // check the version for validity
+ boolean validVersion = true;
+ try {
+ new Version(version);
+ } catch (final IllegalArgumentException iae) {
+ logger.info("Rejecting subsystem {} from {} due to invalid version information: {}.",
+ new Object[] {symbolicName, rsrc, version});
+ validVersion = false;
+ }
+ if ( validVersion ) {
+ result = new SubsystemInfo();
+ result.symbolicName = symbolicName;
+ result.version = version;
+ }
+ }
+ }
+ return result;
+ }
+
+ private ServiceReference<Subsystem> getSubsystemReference(final String symbolicName) {
+ // search a subsystem with the symbolic name
+ ServiceReference<Subsystem> ref = null;
+ try {
+ final Collection<ServiceReference<Subsystem>> refs = this.bundleContext.getServiceReferences(Subsystem.class, "(subsystem.symbolicName=" + symbolicName + ")");
+ if ( refs.size() > 0 ) {
+ ref = refs.iterator().next();
+ }
+ } catch (final InvalidSyntaxException e) {
+ logger.error("Problem searching for subsystem with symbolic name " + symbolicName, e);
+ }
+ return ref;
+ }
+
+ /**
+ * @see org.apache.sling.installer.api.tasks.InstallTaskFactory#createTask(org.apache.sling.installer.api.tasks.TaskResourceGroup)
+ */
+ public InstallTask createTask(final TaskResourceGroup toActivate) {
+ final InstallTask result;
+
+ final TaskResource rsrc = toActivate.getActiveResource();
+ if ( rsrc.getType().equals(TYPE_SUBSYSTEM) ) {
+
+ // check if the required info is available
+ final SubsystemInfo info = checkResource(toActivate);
+ if ( info == null ) {
+ // ignore as info is missing
+ result = new ChangeStateTask(toActivate, ResourceState.IGNORED);
+ } else {
+ // search a subsystem with the symbolic name
+ final ServiceReference<Subsystem> ref = this.getSubsystemReference(info.symbolicName);
+
+ final Version newVersion = new Version(info.version);
+ final Version oldVersion = (ref == null ? null : (Version)ref.getProperty("subsystem.version"));
+
+ // Install
+ if ( rsrc.getState() == ResourceState.INSTALL ) {
+ if ( oldVersion != null ) {
+
+ final int compare = oldVersion.compareTo(newVersion);
+ if (compare < 0) {
+ // installed version is lower -> update
+ result = new UpdateSubsystemTask(toActivate, this.bundleContext, ref, this.rootSubsystem);
+ } else {
+ // TODO - support SNAPSHOT?
+ logger.debug("{} is not installed, subsystem with same or higher version is already installed: {}", info, newVersion);
+ result = new ChangeStateTask(toActivate, ResourceState.IGNORED);
+ }
+ } else {
+ result = new InstallSubsystemTask(toActivate, this.rootSubsystem);
+ }
+
+ // Uninstall
+ } else if ( rsrc.getState() == ResourceState.UNINSTALL ) {
+ if ( oldVersion == null ) {
+ logger.error("Nothing to uninstall. {} is currently not installed.", info);
+ result = new ChangeStateTask(toActivate, ResourceState.IGNORED);
+ } else {
+
+ final int compare = oldVersion.compareTo(newVersion);
+ if ( compare == 0 ) {
+ result = new UninstallSubsystemTask(toActivate, this.bundleContext, ref);
+ } else {
+ logger.error("Nothing to uninstall. {} is currently not installed, different version is installed {}", info, oldVersion);
+ result = new ChangeStateTask(toActivate, ResourceState.IGNORED);
+ }
+ }
+ } else {
+ result = null;
+ }
+ }
+ } else {
+ result = null;
+ }
+ return result;
+ }
+
+ /**
+ * Read the manifest from supplied input stream, which is closed before return.
+ */
+ private static Manifest getManifest(final RegisteredResource rsrc, final Logger logger)
+ throws IOException {
+ final InputStream ins = rsrc.getInputStream();
+
+ Manifest result = null;
+
+ if ( ins != null ) {
+ JarInputStream jis = null;
+ try {
+ jis = new JarInputStream(ins);
+ result = jis.getManifest();
+
+ // SLING-2288 : if this is a jar file, but the manifest is not the first entry
+ // log a warning
+ if ( rsrc.getURL().endsWith(".jar") && result == null ) {
+ logger.warn("Resource {} does not have the manifest as its first entry in the archive. If this is " +
+ "a subsystem, make sure to put the manifest first in the jar file.", rsrc.getURL());
+ }
+ } finally {
+
+ // close the jar stream or the input stream, if the jar
+ // stream is set, we don't need to close the input stream
+ // since closing the jar stream closes the input stream
+ if (jis != null) {
+ try {
+ jis.close();
+ } catch (IOException ignore) {
+ }
+ } else {
+ try {
+ ins.close();
+ } catch (IOException ignore) {
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ final static public class SubsystemInfo {
+ public String symbolicName;
+ public String version;
+ @Override
+
+ public String toString() {
+ return "Subsystem[symbolicName=" + symbolicName + ", version="
+ + version + "]";
+ }
+
+ }
+
+ /**
+ * Read the subsystem info from the manifest (if available)
+ */
+ private SubsystemInfo readSubsystemHeaders(final RegisteredResource resource) {
+ try {
+ final Manifest m = SubsystemInstaller.getManifest(resource, logger);
+ if (m != null) {
+ final String sn = m.getMainAttributes().getValue(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME);
+ if (sn != null) {
+ final String v = m.getMainAttributes().getValue(SubsystemConstants.SUBSYSTEM_VERSION);
+ final int paramPos = sn.indexOf(';');
+ final String symbolicName = (paramPos == -1 ? sn : sn.substring(0, paramPos));
+ final SubsystemInfo headers = new SubsystemInfo();
+ headers.symbolicName = symbolicName;
+ headers.version = v;
+
+ // if no version is specified, use default version
+ if ( headers.version == null ) {
+ headers.version = "0.0.0.0";
+ }
+ return headers;
+ }
+ }
+ } catch (final IOException ignore) {
+ // ignore
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/org/apache/sling/installer/factories/subsystems/impl/UninstallSubsystemTask.java b/src/main/java/org/apache/sling/installer/factories/subsystems/impl/UninstallSubsystemTask.java
new file mode 100644
index 0000000..4ae0dab
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/factories/subsystems/impl/UninstallSubsystemTask.java
@@ -0,0 +1,73 @@
+/*
+ * 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.factories.subsystems.impl;
+
+import org.apache.sling.installer.api.tasks.ChangeStateTask;
+import org.apache.sling.installer.api.tasks.InstallTask;
+import org.apache.sling.installer.api.tasks.InstallationContext;
+import org.apache.sling.installer.api.tasks.ResourceState;
+import org.apache.sling.installer.api.tasks.TaskResource;
+import org.apache.sling.installer.api.tasks.TaskResourceGroup;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.subsystem.Subsystem;
+
+public class UninstallSubsystemTask extends InstallTask {
+
+ private static final String INSTALL_ORDER = "52-";
+
+ private final ServiceReference<Subsystem> subsystemReference;
+
+ private final BundleContext bundleContext;
+
+ public UninstallSubsystemTask(final TaskResourceGroup grp,
+ final BundleContext bundleContext,
+ final ServiceReference<Subsystem> ref) {
+ super(grp);
+ this.bundleContext = bundleContext;
+ this.subsystemReference = ref;
+ }
+
+ @Override
+ public void execute(final InstallationContext ctx) {
+ final TaskResource tr = this.getResource();
+ ctx.log("Uninstalling subsystem from {}", tr);
+
+ Subsystem subsystem = null;
+ try {
+ subsystem = this.bundleContext.getService(this.subsystemReference);
+ if ( subsystem != null ) {
+ subsystem.uninstall();
+ ctx.addTaskToCurrentCycle(new ChangeStateTask(this.getResourceGroup(), ResourceState.UNINSTALLED));
+ } else {
+ ctx.log("Unable to uninstall subsystem {}.", tr);
+ ctx.addTaskToCurrentCycle(new ChangeStateTask(this.getResourceGroup(), ResourceState.IGNORED));
+ }
+ } finally {
+ if ( subsystem != null ) {
+ this.bundleContext.ungetService(this.subsystemReference);
+ }
+ }
+ }
+
+ @Override
+ public String getSortKey() {
+ return INSTALL_ORDER + getResource().getURL();
+ }
+}
diff --git a/src/main/java/org/apache/sling/installer/factories/subsystems/impl/UpdateSubsystemTask.java b/src/main/java/org/apache/sling/installer/factories/subsystems/impl/UpdateSubsystemTask.java
new file mode 100644
index 0000000..3da254b
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/factories/subsystems/impl/UpdateSubsystemTask.java
@@ -0,0 +1,77 @@
+/*
+ * 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.factories.subsystems.impl;
+
+import org.apache.sling.installer.api.tasks.ChangeStateTask;
+import org.apache.sling.installer.api.tasks.InstallTask;
+import org.apache.sling.installer.api.tasks.InstallationContext;
+import org.apache.sling.installer.api.tasks.ResourceState;
+import org.apache.sling.installer.api.tasks.TaskResource;
+import org.apache.sling.installer.api.tasks.TaskResourceGroup;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.subsystem.Subsystem;
+
+public class UpdateSubsystemTask extends InstallTask {
+
+ private static final String INSTALL_ORDER = "54-";
+
+ private final Subsystem rootSubsystem;
+
+ private final ServiceReference<Subsystem> subsystemReference;
+
+ private final BundleContext bundleContext;
+
+ public UpdateSubsystemTask(final TaskResourceGroup grp,
+ final BundleContext bundleContext,
+ final ServiceReference<Subsystem> ref,
+ final Subsystem rootSubsystem) {
+ super(grp);
+ this.bundleContext = bundleContext;
+ this.subsystemReference = ref;
+ this.rootSubsystem = rootSubsystem;
+ }
+
+ @Override
+ public void execute(final InstallationContext ctx) {
+ final TaskResource tr = this.getResource();
+ ctx.log("Updating subsystem from {}", tr);
+
+ Subsystem subsystem = null;
+ try {
+ subsystem = this.bundleContext.getService(this.subsystemReference);
+ if ( subsystem != null ) {
+ subsystem.uninstall();
+ ctx.addTaskToCurrentCycle(new InstallSubsystemTask(this.getResourceGroup(), this.rootSubsystem));
+ } else {
+ ctx.log("Unable to update subsystem {}.", tr);
+ ctx.addTaskToCurrentCycle(new ChangeStateTask(this.getResourceGroup(), ResourceState.IGNORED));
+ }
+ } finally {
+ if ( subsystem != null ) {
+ this.bundleContext.ungetService(this.subsystemReference);
+ }
+ }
+ }
+
+ @Override
+ public String getSortKey() {
+ return INSTALL_ORDER + getResource().getURL();
+ }
+}
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.