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 10:16:31 UTC

[sling-org-apache-sling-settings] 06/10: SLING-2662 : Enhance run mode handling

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.settings-1.2.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-settings.git

commit 11b3f5c00c7691c6b2c674b6e27b719518f09d5a
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Nov 14 15:56:51 2012 +0000

    SLING-2662 :  Enhance run mode handling
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/settings@1409238 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |   2 +-
 .../sling/settings/SlingSettingsService.java       |  16 +++
 .../settings/impl/SlingSettingsServiceImpl.java    | 141 ++++++++++++++++++--
 .../sling/settings/impl/RunModeImplTest.java       | 146 +++++++++++++++++++--
 4 files changed, 278 insertions(+), 27 deletions(-)

diff --git a/pom.xml b/pom.xml
index 3692eb1..ac89c2c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -65,7 +65,7 @@
                             http://sling.apache.org/site/sling-settings-orgapacheslingsettings.html
                         </Bundle-DocURL>
                         <Export-Package>
-                            org.apache.sling.settings;version=1.1.0
+                            org.apache.sling.settings;version=1.2.0
                         </Export-Package>
                         <Private-Package>
                             org.apache.sling.settings.impl
diff --git a/src/main/java/org/apache/sling/settings/SlingSettingsService.java b/src/main/java/org/apache/sling/settings/SlingSettingsService.java
index cd5e175..935400b 100644
--- a/src/main/java/org/apache/sling/settings/SlingSettingsService.java
+++ b/src/main/java/org/apache/sling/settings/SlingSettingsService.java
@@ -68,6 +68,22 @@ public interface SlingSettingsService {
     String RUN_MODES_PROPERTY = "sling.run.modes";
 
     /**
+     * The name of the framework property defining the list
+     * of run mode options
+     * The value is a comma separated list of options where each option
+     * contains of a set of run modes separated by a | character.
+     */
+    String RUN_MODE_OPTIONS = "sling.run.mode.options";
+
+    /**
+     * The name of the framework property defining the list
+     * of run mode options for installation time.
+     * The value is a comma separated list of options where each option
+     * contains of a set of run modes separated by a | character.
+     */
+    String RUN_MODE_INSTALL_OPTIONS = "sling.run.mode.install.options";
+
+    /**
      * Utility method to generate an absolute path
      * within Sling Home.
      *
diff --git a/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java b/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java
index 358b588..89c2588 100644
--- a/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java
+++ b/src/main/java/org/apache/sling/settings/impl/SlingSettingsServiceImpl.java
@@ -22,10 +22,15 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import java.util.UUID;
 
@@ -57,6 +62,9 @@ public class SlingSettingsServiceImpl
     /** The name of the data file holding the sling id. */
     private static final String DATA_FILE = "sling.id.file";
 
+    /** The name of the data file holding install run mode options */
+    private static final String OPTIONS_FILE = "sling.options.file";
+
     /**
      * Create the service and search the Sling home urls and
      * get/create a sling id.
@@ -65,8 +73,8 @@ public class SlingSettingsServiceImpl
      */
     public SlingSettingsServiceImpl(final BundleContext context) {
         this.setupSlingHome(context);
-        this.setupSlingId(context);
-        this.setupRunModes(context);
+        final boolean isInstall = this.setupSlingId(context);
+        this.setupRunModes(context, isInstall);
 
     }
 
@@ -88,7 +96,7 @@ public class SlingSettingsServiceImpl
     /**
      * Get / create sling id
      */
-    private void setupSlingId(final BundleContext context) {
+    private boolean setupSlingId(final BundleContext context) {
         // try to read the id from the id file first
         final File idFile = context.getDataFile(DATA_FILE);
         if ( idFile == null ) {
@@ -101,26 +109,131 @@ 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 {
+        private static final long serialVersionUID = 1L;
+        String[] modes;
+        String   selected;
+    }
+
+    private List<Options> handleOptions(final Set<String> modesSet, final String propOptions) {
+        if ( propOptions != null && propOptions.trim().length() > 0 ) {
+            final List<Options> optionsList = new ArrayList<Options>();
+
+            final String[] options = propOptions.trim().split("\\|");
+            for(final String opt : options) {
+                String selected = null;
+                final String[] modes = opt.trim().split(",");
+                for(int i=0; i<modes.length; i++) {
+                    modes[i] = modes[i].trim();
+                    if ( selected != null ) {
+                        modesSet.remove(modes[i]);
+                    } else {
+                        if ( modesSet.contains(modes[i]) ) {
+                            selected = modes[i];
+                        }
+                    }
+                }
+                if ( selected == null ) {
+                    selected = modes[0];
+                    modesSet.add(modes[0]);
+                }
+                final Options o = new Options();
+                o.selected = selected;
+                o.modes = modes;
+                optionsList.add(o);
+            }
+            return optionsList;
+        }
+        return null;
     }
 
     /**
      * Set up run modes.
      */
-    private void setupRunModes(final BundleContext context) {
+    @SuppressWarnings("unchecked")
+    private void setupRunModes(final BundleContext context,
+            final boolean isInstall) {
+        final Set<String> modesSet = new HashSet<String>();
+
+        // check configuration property first
         final String prop = context.getProperty(RUN_MODES_PROPERTY);
-        if (prop == null || prop.trim().length() == 0) {
-            this.runModes = Collections.emptySet();
-        } else {
-            final Set<String> modesSet = new HashSet<String>();
+        if (prop != null && prop.trim().length() > 0) {
             final String[] modes = prop.split(",");
             for(int i=0; i < modes.length; i++) {
                 modesSet.add(modes[i].trim());
             }
-            // make the set unmodifiable and synced
-            // we propably don't need a synced set as it is read only
-            this.runModes = Collections.synchronizedSet(Collections.unmodifiableSet(modesSet));
-            logger.info("Active run modes {}", this.runModes);
+        }
+
+        // now options
+        this.handleOptions(modesSet, context.getProperty(RUN_MODE_OPTIONS));
+        // now install options
+        if ( isInstall ) {
+            final List<Options> optionsList = this.handleOptions(modesSet, context.getProperty(RUN_MODE_INSTALL_OPTIONS));
+            if ( optionsList != null ) {
+                final File file = context.getDataFile(OPTIONS_FILE);
+                FileOutputStream fos = null;
+                ObjectOutputStream oos = null;
+                try {
+                    fos = new FileOutputStream(file);
+                    oos = new ObjectOutputStream(fos);
+                    oos.writeObject(optionsList);
+                } catch ( final IOException ioe ) {
+                    throw new RuntimeException("Unable to write to options data file.", ioe);
+                } finally {
+                    if ( oos != null ) {
+                        try { oos.close(); } catch ( final IOException ignore) {}
+                    }
+                    if ( fos != null ) {
+                        try { fos.close(); } catch ( final IOException ignore) {}
+                    }
+                }
+            }
+        } else {
+            final File file = context.getDataFile(OPTIONS_FILE);
+            if ( file.exists() ) {
+                List<Options> optionsList = null;
+                FileInputStream fis = null;
+                ObjectInputStream ois = null;
+                try {
+                    fis = new FileInputStream(file);
+                    ois = new ObjectInputStream(fis);
+
+                    optionsList = (List<Options>) ois.readObject();
+                } catch ( final IOException ioe ) {
+                    throw new RuntimeException("Unable to read from options data file.", ioe);
+                } catch (ClassNotFoundException cnfe) {
+                    throw new RuntimeException("Unable to read from options data file.", cnfe);
+                } finally {
+                    if ( ois != null ) {
+                        try { ois.close(); } catch ( final IOException ignore) {}
+                    }
+                    if ( ois != null ) {
+                        try { ois.close(); } catch ( final IOException ignore) {}
+                    }
+                }
+                if ( optionsList != null ) {
+                    for(final Options o : optionsList) {
+                        for(final String m : o.modes) {
+                            modesSet.remove(m);
+                        }
+                        modesSet.add(o.selected);
+                    }
+                }
+            }
+        }
+
+        // make the set unmodifiable and synced
+        // we probably don't need a synced set as it is read only
+        this.runModes = Collections.synchronizedSet(Collections.unmodifiableSet(modesSet));
+        if ( this.runModes.size() > 0 ) {
+            logger.info("Active run modes: {}", this.runModes);
+        } else {
+            logger.info("No run modes active");
         }
     }
 
@@ -143,7 +256,7 @@ public class SlingSettingsServiceImpl
 
                     return id;
                 }
-            } catch (Throwable t) {
+            } catch (final Throwable t) {
                 logger.error("Failed reading UUID from id file " + idFile
                         + ", creating new id", t);
             } finally {
@@ -169,7 +282,7 @@ public class SlingSettingsServiceImpl
             fout = new FileOutputStream(idFile);
             fout.write(slingId.getBytes("ISO-8859-1"));
             fout.flush();
-        } catch (Throwable t) {
+        } catch (final Throwable t) {
             logger.error("Failed writing UUID to id file " + idFile, t);
         } finally {
             if (fout != null) {
diff --git a/src/test/java/org/apache/sling/settings/impl/RunModeImplTest.java b/src/test/java/org/apache/sling/settings/impl/RunModeImplTest.java
index 3235e0b..81a44ae 100644
--- a/src/test/java/org/apache/sling/settings/impl/RunModeImplTest.java
+++ b/src/test/java/org/apache/sling/settings/impl/RunModeImplTest.java
@@ -26,6 +26,8 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.sling.settings.SlingSettingsService;
@@ -43,7 +45,7 @@ import org.osgi.framework.ServiceRegistration;
 public class RunModeImplTest {
 
     private void assertParse(String str, String [] expected) {
-        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock(str));
+        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock(str, null, null));
         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 +59,7 @@ public class RunModeImplTest {
     }
 
     @org.junit.Test public void testMatchesNotEmpty() {
-        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar"));
+        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar", null, null));
 
         assertTrue("single foo should be active", rm.getRunModes().contains("foo"));
 
@@ -66,12 +68,121 @@ public class RunModeImplTest {
         assertFalse("empty should be not active", rm.getRunModes().contains(""));
     }
 
+    @org.junit.Test public void testOptions() {
+        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar", "a,b,c|d,e,f", null));
+        assertTrue("foo should be active", rm.getRunModes().contains("foo"));
+        assertTrue("bar should be active", rm.getRunModes().contains("bar"));
+        assertTrue("a should be active", rm.getRunModes().contains("a"));
+        assertTrue("d should be active", rm.getRunModes().contains("d"));
+        assertFalse("b should not be active", rm.getRunModes().contains("b"));
+        assertFalse("c should not be active", rm.getRunModes().contains("c"));
+        assertFalse("e should not be active", rm.getRunModes().contains("e"));
+        assertFalse("f should not be active", rm.getRunModes().contains("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));
+        assertTrue("foo should be active", rm.getRunModes().contains("foo"));
+        assertTrue("bar should be active", rm.getRunModes().contains("bar"));
+        assertTrue("c should be active", rm.getRunModes().contains("c"));
+        assertTrue("e should be active", rm.getRunModes().contains("e"));
+        assertFalse("a should not be active", rm.getRunModes().contains("a"));
+        assertFalse("b should not be active", rm.getRunModes().contains("b"));
+        assertFalse("d should not be active", rm.getRunModes().contains("d"));
+        assertFalse("f should not be active", rm.getRunModes().contains("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));
+        assertTrue("foo should be active", rm.getRunModes().contains("foo"));
+        assertTrue("bar should be active", rm.getRunModes().contains("bar"));
+        assertTrue("a should be active", rm.getRunModes().contains("a"));
+        assertTrue("e should be active", rm.getRunModes().contains("e"));
+        assertFalse("b should not be active", rm.getRunModes().contains("b"));
+        assertFalse("c should not be active", rm.getRunModes().contains("c"));
+        assertFalse("d should not be active", rm.getRunModes().contains("d"));
+        assertFalse("f should not be active", rm.getRunModes().contains("f"));
+    }
+
+    @org.junit.Test public void testInstallOptions() {
+        final SlingSettingsService rm = new SlingSettingsServiceImpl(new BundleContextMock("foo,bar", null, "a,b,c|d,e,f"));
+        assertTrue("foo should be active", rm.getRunModes().contains("foo"));
+        assertTrue("bar should be active", rm.getRunModes().contains("bar"));
+        assertTrue("a should be active", rm.getRunModes().contains("a"));
+        assertTrue("d should be active", rm.getRunModes().contains("d"));
+        assertFalse("b should not be active", rm.getRunModes().contains("b"));
+        assertFalse("c should not be active", rm.getRunModes().contains("c"));
+        assertFalse("e should not be active", rm.getRunModes().contains("e"));
+        assertFalse("f should not be active", rm.getRunModes().contains("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"));
+        assertTrue("foo should be active", rm.getRunModes().contains("foo"));
+        assertTrue("bar should be active", rm.getRunModes().contains("bar"));
+        assertTrue("c should be active", rm.getRunModes().contains("c"));
+        assertTrue("e should be active", rm.getRunModes().contains("e"));
+        assertFalse("a should not be active", rm.getRunModes().contains("a"));
+        assertFalse("b should not be active", rm.getRunModes().contains("b"));
+        assertFalse("d should not be active", rm.getRunModes().contains("d"));
+        assertFalse("f should not be active", rm.getRunModes().contains("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"));
+        assertTrue("foo should be active", rm.getRunModes().contains("foo"));
+        assertTrue("bar should be active", rm.getRunModes().contains("bar"));
+        assertTrue("a should be active", rm.getRunModes().contains("a"));
+        assertTrue("e should be active", rm.getRunModes().contains("e"));
+        assertFalse("b should not be active", rm.getRunModes().contains("b"));
+        assertFalse("c should not be active", rm.getRunModes().contains("c"));
+        assertFalse("d should not be active", rm.getRunModes().contains("d"));
+        assertFalse("f should not be active", rm.getRunModes().contains("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");
+        new SlingSettingsServiceImpl(bc); // first context to simulate install
+        final SlingSettingsService rm = new SlingSettingsServiceImpl(bc);
+        assertTrue("foo should be active", rm.getRunModes().contains("foo"));
+        assertTrue("bar should be active", rm.getRunModes().contains("bar"));
+        assertTrue("a should be active", rm.getRunModes().contains("a"));
+        assertTrue("e should be active", rm.getRunModes().contains("e"));
+        assertFalse("b should not be active", rm.getRunModes().contains("b"));
+        assertFalse("c should not be active", rm.getRunModes().contains("c"));
+        assertFalse("d should not be active", rm.getRunModes().contains("d"));
+        assertFalse("f should not be active", rm.getRunModes().contains("f"));
+
+        // and another restart with different run modes
+        bc.update("foo,doo,a,b,c,d,e,f");
+        final SlingSettingsService rm2 = new SlingSettingsServiceImpl(bc);
+        assertTrue("foo should be active", rm2.getRunModes().contains("foo"));
+        assertTrue("doo should be active", rm2.getRunModes().contains("doo"));
+        assertTrue("a should be active", rm2.getRunModes().contains("a"));
+        assertTrue("e should be active", rm2.getRunModes().contains("e"));
+        assertFalse("bar should not be active", rm2.getRunModes().contains("bar"));
+        assertFalse("b should not be active", rm2.getRunModes().contains("b"));
+        assertFalse("c should not be active", rm2.getRunModes().contains("c"));
+        assertFalse("d should not be active", rm2.getRunModes().contains("d"));
+        assertFalse("f should not be active", rm2.getRunModes().contains("f"));
+    }
+
     private static final class BundleContextMock implements BundleContext {
 
-        private final String str;
+        private String runModes;
+        private final String options;
+        private final String installOptions;
+
+        private final Map<String, File> files = new HashMap<String, File>();
 
-        public BundleContextMock(String str) {
-            this.str = str;
+        public BundleContextMock(String runModes, String options, String installOptions) {
+            this.runModes = runModes;
+            this.options = options;
+            this.installOptions = installOptions;
+        }
+
+        public void update(final String rm) {
+            this.runModes = rm;
         }
 
         public void addBundleListener(BundleListener listener) {
@@ -121,17 +232,28 @@ public class RunModeImplTest {
         }
 
         public File getDataFile(String filename) {
-            try {
-                final File f = File.createTempFile("sling", "id");
-                f.deleteOnExit();
-                return f;
-            } catch (IOException ioe) {
-                throw new RuntimeException(ioe);
+            File f = files.get(filename);
+            if ( f == null ) {
+                try {
+                    f = File.createTempFile(filename, "id");
+                    f.deleteOnExit();
+                    files.put(filename, f);
+                } catch (IOException ioe) {
+                    throw new RuntimeException(ioe);
+                }
             }
+            return f;
         }
 
         public String getProperty(String key) {
-            return str;
+            if ( key.equals(SlingSettingsService.RUN_MODES_PROPERTY) ) {
+                return runModes;
+            } else if ( key.equals(SlingSettingsService.RUN_MODE_OPTIONS) ) {
+                return options;
+            } else if ( key.equals(SlingSettingsService.RUN_MODE_INSTALL_OPTIONS) ) {
+                return installOptions;
+            }
+            return null;
         }
 
         public Object getService(ServiceReference reference) {

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.