sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject svn commit: r1413541 - in /sling/trunk/bundles/extensions/settings/src: main/java/org/apache/sling/settings/impl/ test/java/org/apache/sling/settings/impl/
Date Mon, 26 Nov 2012 10:14:10 GMT
Author: cziegeler
Date: Mon Nov 26 10:14:09 2012
New Revision: 1413541

URL: http://svn.apache.org/viewvc?rev=1413541&view=rev
Log:
SLING-2674 :  SlingSettingsServiceImpl should detect and handle upgrades 

Added:
    sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/ServicesListener.java
  (with props)
Modified:
    sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/Activator.java
    sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java
    sling/trunk/bundles/extensions/settings/src/test/java/org/apache/sling/settings/impl/RunModeImplTest.java

Modified: sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/Activator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/Activator.java?rev=1413541&r1=1413540&r2=1413541&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/Activator.java
(original)
+++ sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/Activator.java
Mon Nov 26 10:14:09 2012
@@ -18,14 +18,8 @@
  */
 package org.apache.sling.settings.impl;
 
-import java.util.Dictionary;
-import java.util.Hashtable;
-
-import org.apache.sling.settings.SlingSettingsService;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceRegistration;
 
 /**
  * This is the bundle activator.
@@ -34,48 +28,23 @@ import org.osgi.framework.ServiceRegistr
  */
 public class Activator implements BundleActivator {
 
-    /** The service registration */
-    private ServiceRegistration serviceRegistration;
+    /** The service listener */
+    private ServicesListener servicesListener;
 
     /**
      * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
      */
     public void start(final BundleContext bundleContext) throws Exception {
-        final SlingSettingsService settingsService = new SlingSettingsServiceImpl(bundleContext);
-
-        final Dictionary<String, String> props = new Hashtable<String, String>();
-        props.put(Constants.SERVICE_PID, settingsService.getClass().getName());
-        props.put(Constants.SERVICE_DESCRIPTION,
-            "Apache Sling Settings Service");
-        props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
-        serviceRegistration = bundleContext.registerService(new String[] {
-                                               SlingSettingsService.class.getName()},
-                                               settingsService, props);
-        SlingPropertiesPrinter.initPlugin(bundleContext);
-        SlingSettingsPrinter.initPlugin(bundleContext, settingsService);
-        try {
-            RunModeCommand.initPlugin(bundleContext, settingsService.getRunModes());
-        } catch (Throwable ignore) {
-            // we just ignore this
-        }
-
+        this.servicesListener = new ServicesListener(bundleContext);
     }
 
     /**
      * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
      */
     public void stop(final BundleContext context) throws Exception {
-        try {
-            RunModeCommand.destroyPlugin();
-        } catch (Throwable ignore) {
-            // we just ignore this
-        }
-        SlingSettingsPrinter.destroyPlugin();
-        SlingPropertiesPrinter.destroyPlugin();
-
-        if ( serviceRegistration != null ) {
-            serviceRegistration.unregister();
-            serviceRegistration = null;
+        if ( this.servicesListener != null ) {
+            this.servicesListener.deactivate();
+            this.servicesListener = null;
         }
     }
 }

Added: sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/ServicesListener.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/ServicesListener.java?rev=1413541&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/ServicesListener.java
(added)
+++ sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/ServicesListener.java
Mon Nov 26 10:14:09 2012
@@ -0,0 +1,199 @@
+/*
+ * 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.settings.impl;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.sling.launchpad.api.StartupHandler;
+import org.apache.sling.settings.SlingSettingsService;
+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;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * The <code>ServicesListener</code> listens for the required services
+ * and registers the settings service once all required services are
+ * available
+ */
+public class ServicesListener {
+
+    /** The bundle context. */
+    private final BundleContext bundleContext;
+
+    /** The listener for the startup handler. */
+    private final Listener startupListener;
+
+    /** The registration of the settings service. */
+    private ServiceRegistration settingsReg;
+
+    /**
+     * Start listeners
+     */
+    public ServicesListener(final BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+        this.startupListener = new Listener(StartupHandler.class.getName());
+        this.startupListener.start();
+    }
+
+    /**
+     * Notify of service changes from the listeners.
+     * If all services are available, register listener and pass resources
+     * to the OSGi installer.
+     */
+    public synchronized void notifyChange() {
+        // check if all services are available
+        final StartupHandler handler = (StartupHandler)this.startupListener.getService();
+        if ( handler != null && this.settingsReg == null ) {
+            this.activate(handler);
+        }
+    }
+
+    private void activate(final StartupHandler handler) {
+        final SlingSettingsService settingsService = new SlingSettingsServiceImpl(bundleContext,
handler);
+
+        final Dictionary<String, String> props = new Hashtable<String, String>();
+        props.put(Constants.SERVICE_PID, settingsService.getClass().getName());
+        props.put(Constants.SERVICE_DESCRIPTION,
+            "Apache Sling Settings Service");
+        props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+        this.settingsReg = bundleContext.registerService(new String[] {
+                                               SlingSettingsService.class.getName()},
+                                               settingsService, props);
+        SlingPropertiesPrinter.initPlugin(bundleContext);
+        SlingSettingsPrinter.initPlugin(bundleContext, settingsService);
+        try {
+            RunModeCommand.initPlugin(bundleContext, settingsService.getRunModes());
+        } catch (Throwable ignore) {
+            // we just ignore this
+        }
+    }
+    /**
+     * Deactivate this listener.
+     */
+    public void deactivate() {
+        this.startupListener.deactivate();
+        if ( this.settingsReg != null ) {
+            this.settingsReg.unregister();
+            this.settingsReg = null;
+        }
+        try {
+            RunModeCommand.destroyPlugin();
+        } catch (Throwable ignore) {
+            // we just ignore this
+        }
+        SlingSettingsPrinter.destroyPlugin();
+        SlingPropertiesPrinter.destroyPlugin();
+    }
+
+    /**
+     * Helper class listening for service events for a defined service.
+     */
+    protected final class Listener implements ServiceListener {
+
+        /** The name of the service. */
+        private final String serviceName;
+
+        /** The service reference. */
+        private volatile ServiceReference reference;
+
+        /** The service. */
+        private volatile Object service;
+
+        /**
+         * Constructor
+         */
+        public Listener(final String serviceName) {
+            this.serviceName = serviceName;
+        }
+
+        /**
+         * Start the listener.
+         * First register a service listener and then check for the service.
+         */
+        public void start() {
+            try {
+                bundleContext.addServiceListener(this, "("
+                        + Constants.OBJECTCLASS + "=" + serviceName + ")");
+            } catch (final InvalidSyntaxException ise) {
+                // this should really never happen
+                throw new RuntimeException("Unexpected exception occured.", ise);
+            }
+            this.retainService();
+        }
+
+        /**
+         * Unregister the listener.
+         */
+        public void deactivate() {
+            bundleContext.removeServiceListener(this);
+        }
+
+        /**
+         * Return the service (if available)
+         */
+        public synchronized Object getService() {
+            return this.service;
+        }
+
+        /**
+         * Try to get the service and notify the change.
+         */
+        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();
+                    }
+                }
+            }
+        }
+
+        /**
+         * Try to release the service and notify the change.
+         */
+        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.retainService();
+            } else if ( event.getType() == ServiceEvent.UNREGISTERING ) {
+                this.releaseService();
+            }
+        }
+    }
+}

Propchange: sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/ServicesListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/ServicesListener.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/ServicesListener.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java?rev=1413541&r1=1413540&r2=1413541&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java
(original)
+++ sling/trunk/bundles/extensions/settings/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java
Mon Nov 26 10:14:09 2012
@@ -34,6 +34,7 @@ import java.util.List;
 import java.util.Set;
 import java.util.UUID;
 
+import org.apache.sling.launchpad.api.StartupHandler;
 import org.apache.sling.launchpad.api.StartupMode;
 import org.apache.sling.settings.SlingSettingsService;
 import org.osgi.framework.BundleContext;
@@ -72,24 +73,13 @@ public class SlingSettingsServiceImpl
      * Setup run modes
      * @param context The bundle context
      */
-    public SlingSettingsServiceImpl(final BundleContext context) {
+    public SlingSettingsServiceImpl(final BundleContext context,
+            final StartupHandler handler) {
         this.setupSlingHome(context);
-        final boolean isInstall = this.setupSlingId(context);
+        this.setupSlingId(context);
 
-        // Detect if upgrading from a previous version (where OPTIONS_FILE did not exist),
-        // as in terms of run modes this needs to be handled like an install
-        final File options = context.getDataFile(OPTIONS_FILE);
-        final boolean isUpdate = !isInstall && !options.exists();
-
-        final String startupModeObj = context.getProperty(StartupMode.class.getName());
-        final StartupMode mode;
-        if ( startupModeObj != null ) {
-            mode = StartupMode.valueOf(startupModeObj);
-            logger.debug("Settings: Using startup mode : {}", mode);
-        } else {
-            logger.debug("Settings: Startup mode detection: isInstall={}, isUpdate={}", isInstall,
isUpdate);
-            mode = isInstall ? StartupMode.INSTALL : (isUpdate ? StartupMode.UPDATE : StartupMode.RESTART);
-        }
+        final StartupMode mode = handler.getMode();
+        logger.debug("Settings: Using startup mode : {}", mode);
 
         this.setupRunModes(context, mode);
 
@@ -113,7 +103,7 @@ public class SlingSettingsServiceImpl
     /**
      * Get / create sling id
      */
-    private boolean setupSlingId(final BundleContext context) {
+    private void setupSlingId(final BundleContext context) {
         // try to read the id from the id file first
         final File idFile = context.getDataFile(DATA_FILE);
         if ( idFile == null ) {
@@ -126,9 +116,7 @@ public class SlingSettingsServiceImpl
         if (slingId == null) {
             slingId = UUID.randomUUID().toString();
             this.writeSlingId(idFile, this.slingId);
-            return true;
         }
-        return false;
     }
 
     private static final class Options implements Serializable {

Modified: sling/trunk/bundles/extensions/settings/src/test/java/org/apache/sling/settings/impl/RunModeImplTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/settings/src/test/java/org/apache/sling/settings/impl/RunModeImplTest.java?rev=1413541&r1=1413540&r2=1413541&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/settings/src/test/java/org/apache/sling/settings/impl/RunModeImplTest.java
(original)
+++ sling/trunk/bundles/extensions/settings/src/test/java/org/apache/sling/settings/impl/RunModeImplTest.java
Mon Nov 26 10:14:09 2012
@@ -30,6 +30,8 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.sling.launchpad.api.StartupHandler;
+import org.apache.sling.launchpad.api.StartupMode;
 import org.apache.sling.settings.SlingSettingsService;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -44,8 +46,33 @@ import org.osgi.framework.ServiceRegistr
 
 public class RunModeImplTest {
 
+    private final class StartupHandlerImpl implements StartupHandler {
+
+        private final StartupMode mode;
+
+        public StartupHandlerImpl() {
+            this(StartupMode.INSTALL);
+        }
+
+        public StartupHandlerImpl(final StartupMode mode) {
+            this.mode = mode;
+        }
+
+        public void waitWithStartup(final boolean flag) {
+            // nothing to do
+        }
+
+        public boolean isFinished() {
+            return false;
+        }
+
+        public StartupMode getMode() {
+            return this.mode;
+        }
+    };
+
     private void assertParse(String str, String [] expected) {
-        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock(str,
null, null));
+        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock(str,
null, null), new StartupHandlerImpl());
         final Set<String> modes = rm.getRunModes();
         final String[] actual = modes.toArray(new String[modes.size()]);
         assertArrayEquals("Parsed runModes match for '" + str + "'", expected, actual);
@@ -57,7 +84,7 @@ public class RunModeImplTest {
         assertParse(" foo \t", new String[] { "foo" });
         assertParse(" foo \t,  bar\n", new String[] { "foo", "bar" });
     }
-    
+
     private void assertActive(SlingSettingsService s, boolean active, String ...modes) {
         for(String mode : modes) {
             if(active) {
@@ -69,77 +96,77 @@ public class RunModeImplTest {
     }
 
     @org.junit.Test public void testMatchesNotEmpty() {
-        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar",
null, null));
+        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar",
null, null), new StartupHandlerImpl());
         assertActive(rm, true, "foo", "bar");
         assertActive(rm, false, "wiz", "bah", "");
     }
 
     @org.junit.Test public void testOptions() {
-        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar",
"a,b,c|d,e,f", null));
+        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar",
"a,b,c|d,e,f", null), new StartupHandlerImpl());
         assertActive(rm, true, "foo", "bar", "a", "d");
         assertActive(rm, false, "b", "c", "e", "f");
     }
 
     @org.junit.Test public void testEmptyRunModesWithOptions() {
-        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("",
"a,b,c|d,e,f", null));
+        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("",
"a,b,c|d,e,f", null), new StartupHandlerImpl());
         assertActive(rm, true, "a", "d");
         assertActive(rm, false, "b", "c", "e", "f");
     }
 
     @org.junit.Test public void testOptionsSelected() {
-        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar,c,e",
"a,b,c|d,e,f", null));
+        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar,c,e",
"a,b,c|d,e,f", null), new StartupHandlerImpl());
         assertActive(rm, true, "foo", "bar", "c", "e");
         assertActive(rm, false, "a", "b", "d", "f");
     }
 
     @org.junit.Test public void testOptionsMultipleSelected() {
-        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar,c,e,f,a",
"a,b,c|d,e,f", null));
+        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar,c,e,f,a",
"a,b,c|d,e,f", null), new StartupHandlerImpl());
         assertActive(rm, true, "foo", "bar", "a", "e");
         assertActive(rm, false, "b", "c", "d", "f");
     }
 
     @org.junit.Test public void testOptionsMultipleSelected2() {
-        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar,c,f,a,d",
"a,b,c|d,e,f", null));
+        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar,c,f,a,d",
"a,b,c|d,e,f", null), new StartupHandlerImpl());
         assertActive(rm, true, "foo", "bar", "a", "d");
         assertActive(rm, false, "b", "c", "e", "f");
     }
 
     @org.junit.Test public void testInstallOptions() {
-        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar",
null, "a,b,c|d,e,f"));
+        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar",
null, "a,b,c|d,e,f"), new StartupHandlerImpl());
         assertActive(rm, true, "foo", "bar", "a", "d");
         assertActive(rm, false, "b", "c", "e", "f");
     }
 
     @org.junit.Test public void testInstallOptionsSelected() {
-        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar,c,e",
null , "a,b,c|d,e,f"));
+        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar,c,e",
null , "a,b,c|d,e,f"), new StartupHandlerImpl());
         assertActive(rm, true, "foo", "bar", "c", "e");
         assertActive(rm, false, "a", "b", "d", "f");
     }
 
     @org.junit.Test public void testInstallOptionsMultipleSelected() {
-        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar,c,e,f,a",
null, "a,b,c|d,e,f"));
+        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar,c,e,f,a",
null, "a,b,c|d,e,f"), new StartupHandlerImpl());
         assertActive(rm, true, "foo", "bar", "a", "e");
         assertActive(rm, false, "b", "c", "d", "f");
     }
 
     @org.junit.Test public void testInstallOptionsMultipleSelected2() {
-        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar,c,d,f,a",
null, "a,b,c|d,e,f"));
+        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar,c,d,f,a",
null, "a,b,c|d,e,f"), new StartupHandlerImpl());
         assertActive(rm, true, "foo", "bar", "a", "d");
         assertActive(rm, false, "b", "c", "e", "f");
     }
 
     @org.junit.Test public void testInstallOptionsRestart() {
         final BundleContextMock bc = new BundleContextMock("foo,bar,c,e,f,a", null, "a,b,c|d,e,f");
-        
+
         {
             // create first context to simulate install
-            final SlingSettingsService rm = new SlingSettingsServiceImpl(bc);
+            final SlingSettingsService rm = new SlingSettingsServiceImpl(bc, new StartupHandlerImpl());
             assertActive(rm, true, "foo", "bar", "a", "e");
             assertActive(rm, false, "b", "c", "d", "f");
         }
-        
+
         {
-            final SlingSettingsService rm = new SlingSettingsServiceImpl(bc);
+            final SlingSettingsService rm = new SlingSettingsServiceImpl(bc, new StartupHandlerImpl(StartupMode.RESTART));
             assertActive(rm, true, "foo", "bar", "a", "e");
             assertActive(rm, false, "b", "c", "d", "f");
         }
@@ -148,7 +175,7 @@ public class RunModeImplTest {
         // mentioned in the .options properties are ignored
         bc.update("foo,doo,a,b,c,d,e,f,waa");
         {
-            final SlingSettingsService rm = new SlingSettingsServiceImpl(bc);
+            final SlingSettingsService rm = new SlingSettingsServiceImpl(bc, new StartupHandlerImpl(StartupMode.RESTART));
             assertActive(rm, true, "foo", "doo", "a", "e", "waa");
             assertActive(rm, false, "bar", "b", "c", "d", "f");
         }



Mime
View raw message