SLING-1954 : Launchpad installer should not depend on SCR
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1063204 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index 9bdaa82..ac8d459 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,31 +38,16 @@
<extensions>true</extensions>
<configuration>
<instructions>
+ <Bundle-Activator>
+ org.apache.sling.launchpad.installer.impl.Activator
+ </Bundle-Activator>
</instructions>
</configuration>
</plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-scr-plugin</artifactId>
- <executions>
- <execution>
- <id>generate-scr-scrdescriptor</id>
- <goals>
- <goal>scr</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
<dependencies>
<dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.scr.annotations</artifactId>
- <version>1.4.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.launchpad.api</artifactId>
<version>0.0.1-SNAPSHOT</version>
@@ -71,26 +56,16 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.installer.core</artifactId>
- <version>3.0.0</version>
+ <version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
- <version>4.2.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- <version>4.2.0</version>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
- <version>1.5.2</version>
- <scope>provided</scope>
</dependency>
</dependencies>
</project>
diff --git a/src/main/java/org/apache/sling/launchpad/installer/impl/Activator.java b/src/main/java/org/apache/sling/launchpad/installer/impl/Activator.java
new file mode 100644
index 0000000..4363e19
--- /dev/null
+++ b/src/main/java/org/apache/sling/launchpad/installer/impl/Activator.java
@@ -0,0 +1,46 @@
+/*
+ * 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.launchpad.installer.impl;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The <code>Activator</code>
+ */
+public class Activator implements BundleActivator {
+
+ /** The services listener will activate the installer. */
+ private ServicesListener servicesListener;
+
+ /**
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(final BundleContext context) {
+ this.servicesListener = new ServicesListener(context);
+ }
+
+ /**
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(final BundleContext context) {
+ this.servicesListener.deactivate();
+ this.servicesListener = null;
+ }
+}
diff --git a/src/main/java/org/apache/sling/launchpad/installer/impl/LaunchpadConfigInstaller.java b/src/main/java/org/apache/sling/launchpad/installer/impl/LaunchpadConfigInstaller.java
index 91fa78b..82ce5c2 100644
--- a/src/main/java/org/apache/sling/launchpad/installer/impl/LaunchpadConfigInstaller.java
+++ b/src/main/java/org/apache/sling/launchpad/installer/impl/LaunchpadConfigInstaller.java
@@ -5,9 +5,9 @@
* 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
@@ -21,45 +21,36 @@
import java.util.HashSet;
import java.util.Iterator;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.sling.launchpad.api.LaunchpadContentProvider;
import org.apache.sling.installer.api.InstallableResource;
import org.apache.sling.installer.api.OsgiInstaller;
-import org.osgi.service.component.ComponentContext;
+import org.apache.sling.launchpad.api.LaunchpadContentProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-@Component
public class LaunchpadConfigInstaller {
- /** Resources supplied under this path by
+ /** Resources supplied under this path by
* LaunchpadContentProvider are considered for installation
*/
private static final String ROOT_CONFIG_PATH = "resources/config";
- @Reference
- private OsgiInstaller installer;
+ private static Logger LOGGER = LoggerFactory.getLogger(LaunchpadConfigInstaller.class);
- @Reference
- private LaunchpadContentProvider resourceProvider;
-
- private Logger logger = LoggerFactory.getLogger(this.getClass());
-
- protected void activate(ComponentContext componentContext) {
- logger.info("Activating launchpad config installer, resources path={}", ROOT_CONFIG_PATH);
+ public static void install(final OsgiInstaller installer,
+ final LaunchpadContentProvider resourceProvider) {
+ LOGGER.info("Activating launchpad config installer, resources path={}", ROOT_CONFIG_PATH);
Collection<InstallableResource> installables = new HashSet<InstallableResource>();
Iterator<String> configPaths = resourceProvider.getChildren(ROOT_CONFIG_PATH);
while (configPaths.hasNext()) {
String path = configPaths.next();
- logger.info("Config launchpad file will be installed: {}", path);
+ LOGGER.info("Config launchpad file will be installed: {}", path);
InputStream stream = resourceProvider.getResourceAsStream(path);
- installables.add(new InstallableResource(path, stream, null, null, InstallableResource.TYPE_CONFIG, 0));
+ installables.add(new InstallableResource(path, stream, null, null, InstallableResource.TYPE_PROPERTIES, 0));
}
final InstallableResource [] toInstall = installables.toArray(new InstallableResource []{});
installer.registerResources("launchpad", (toInstall));
- logger.info("{} resources registered with OsgiInstaller", toInstall.length);
+ LOGGER.info("{} resources registered with OsgiInstaller", toInstall.length);
}
}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/launchpad/installer/impl/ServicesListener.java b/src/main/java/org/apache/sling/launchpad/installer/impl/ServicesListener.java
new file mode 100644
index 0000000..170c2d0
--- /dev/null
+++ b/src/main/java/org/apache/sling/launchpad/installer/impl/ServicesListener.java
@@ -0,0 +1,135 @@
+/*
+ * 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.launchpad.installer.impl;
+
+import org.apache.sling.installer.api.OsgiInstaller;
+import org.apache.sling.launchpad.api.LaunchpadContentProvider;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The <code>ServicesListener</code> listens for the required services
+ * and starts/stops the scanners based on the availability of the
+ * services.
+ */
+public class ServicesListener {
+
+ /** The bundle context. */
+ private final BundleContext bundleContext;
+
+ /** The listener for the installer. */
+ private final Listener installerListener;
+
+ /** The listener for the provider. */
+ private final Listener providerListener;
+
+ public ServicesListener(final BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ this.installerListener = new Listener(OsgiInstaller.class.getName());
+ this.providerListener = new Listener(LaunchpadContentProvider.class.getName());
+ this.installerListener.start();
+ this.providerListener.start();
+ }
+
+ public synchronized void notifyChange() {
+ // check if all services are available
+ final OsgiInstaller installer = (OsgiInstaller)this.installerListener.getService();
+ final LaunchpadContentProvider lcp = (LaunchpadContentProvider)this.providerListener.getService();
+
+ if ( installer != null && lcp != null ) {
+ LaunchpadConfigInstaller.install(installer, lcp);
+ }
+ }
+
+ /**
+ * Deactivate this listener.
+ */
+ public void deactivate() {
+ this.installerListener.deactivate();
+ this.providerListener.deactivate();
+ }
+
+ protected final class Listener implements ServiceListener {
+
+ private final String serviceName;
+
+ private ServiceReference reference;
+ private Object service;
+
+ public Listener(final String serviceName) {
+ this.serviceName = serviceName;
+ }
+
+ public void start() {
+ this.retainService();
+ try {
+ bundleContext.addServiceListener(this, "("
+ + Constants.OBJECTCLASS + "=" + serviceName + ")");
+ } catch (final InvalidSyntaxException ise) {
+ // this should really never happen
+ throw new RuntimeException("Unexpected exception occured.", ise);
+ }
+ }
+
+ public void deactivate() {
+ bundleContext.removeServiceListener(this);
+ }
+
+ public synchronized Object getService() {
+ return this.service;
+ }
+ private synchronized void retainService() {
+ if ( this.reference == null ) {
+ this.reference = bundleContext.getServiceReference(this.serviceName);
+ if ( this.reference != null ) {
+ this.service = bundleContext.getService(this.reference);
+ if ( this.service == null ) {
+ this.reference = null;
+ } else {
+ notifyChange();
+ }
+ }
+ }
+ }
+
+ private synchronized void releaseService() {
+ if ( this.reference != null ) {
+ this.service = null;
+ bundleContext.ungetService(this.reference);
+ this.reference = null;
+ notifyChange();
+ }
+ }
+
+ /**
+ * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+ */
+ public void serviceChanged(ServiceEvent event) {
+ if (event.getType() == ServiceEvent.REGISTERED && this.service == null ) {
+ this.retainService();
+ } else if ( event.getType() == ServiceEvent.UNREGISTERING && this.service != null ) {
+ this.releaseService();
+ }
+ }
+ }
+}