Author: cschneider
Date: Mon Aug  6 12:54:38 2012
New Revision: 1369825

URL: http://svn.apache.org/viewvc?rev=1369825&view=rev
Log:
KARAF-1640: Porting Guillaumes solution from 2.3.x to trunk

Added:
    karaf/trunk/main/src/main/java/org/apache/karaf/main/StartupListener.java
    
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/impl/jline/DelayedStarted.java
Removed:
    
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/impl/jline/BundleWatcher.java
Modified:
    karaf/trunk/main/src/main/java/org/apache/karaf/main/ConfigProperties.java
    karaf/trunk/main/src/main/java/org/apache/karaf/main/Main.java
    
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/impl/jline/LocalConsoleManager.java

Modified: 
karaf/trunk/main/src/main/java/org/apache/karaf/main/ConfigProperties.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/apache/karaf/main/ConfigProperties.java?rev=1369825&r1=1369824&r2=1369825&view=diff
==============================================================================
--- karaf/trunk/main/src/main/java/org/apache/karaf/main/ConfigProperties.java 
(original)
+++ karaf/trunk/main/src/main/java/org/apache/karaf/main/ConfigProperties.java 
Mon Aug  6 12:54:38 2012
@@ -119,6 +119,8 @@ public class ConfigProperties {
     private static final String PROPERTY_LOCK_CLASS_DEFAULT = 
SimpleFileLock.class.getName();
 
     private static final String SECURITY_PROVIDERS = 
"org.apache.karaf.security.providers";
+    
+    private static final String KARAF_STARTUP_MESSAGE = 
"karaf.startup.message";
 
     /**
      * If a lock should be used before starting the runtime
@@ -151,6 +153,7 @@ public class ConfigProperties {
     String includes;
     String optionals;
     File etcFolder;
+    String startupMessage;
     
     public ConfigProperties() throws Exception {
         this.karafHome = Utils.getKarafHome(ConfigProperties.class, 
PROP_KARAF_HOME, ENV_KARAF_HOME);
@@ -202,6 +205,7 @@ public class ConfigProperties {
         this.shutdownHost = props.getProperty(KARAF_SHUTDOWN_HOST, 
"localhost");
         this.portFile = props.getProperty(KARAF_SHUTDOWN_PORT_FILE);
         this.shutdownCommand = props.getProperty(KARAF_SHUTDOWN_COMMAND, 
DEFAULT_SHUTDOWN_COMMAND);
+        this.startupMessage = props.getProperty(KARAF_STARTUP_MESSAGE, "Apache 
Karaf starting up. Press Enter to open the shell now...");
     }
     
     private String getProperyOrFail(String propertyName) {

Modified: karaf/trunk/main/src/main/java/org/apache/karaf/main/Main.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/apache/karaf/main/Main.java?rev=1369825&r1=1369824&r2=1369825&view=diff
==============================================================================
--- karaf/trunk/main/src/main/java/org/apache/karaf/main/Main.java (original)
+++ karaf/trunk/main/src/main/java/org/apache/karaf/main/Main.java Mon Aug  6 
12:54:38 2012
@@ -210,6 +210,7 @@ public class Main {
 
     public void launch() throws Exception {
         config = new ConfigProperties();
+        System.out.println(config.startupMessage);
         BootstrapLogManager.setProperties(config.props);
         Lock lock = createLock();
         lockManager = new LockManager(lock, new KarafLockCallback(), 
config.lockDelay);
@@ -250,6 +251,8 @@ public class Main {
         activatorManager.startKarafActivators();
         
         setStartLevel(config.lockStartLevel);
+        // Progress bar
+        new StartupListener(framework.getBundleContext());
         lockManager.startLockMonitor();
     }
     

Added: karaf/trunk/main/src/main/java/org/apache/karaf/main/StartupListener.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/main/src/main/java/org/apache/karaf/main/StartupListener.java?rev=1369825&view=auto
==============================================================================
--- karaf/trunk/main/src/main/java/org/apache/karaf/main/StartupListener.java 
(added)
+++ karaf/trunk/main/src/main/java/org/apache/karaf/main/StartupListener.java 
Mon Aug  6 12:54:38 2012
@@ -0,0 +1,72 @@
+package org.apache.karaf.main;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.framework.startlevel.FrameworkStartLevel;
+
+/**
+ * Watches the startup of the framework and displays a progress bar of the 
number of bundles started / total.
+ * The listener will remove itself after the desired start level is reached or 
the system property karaf.console.started is set to 
+ * true. 
+ */
+class StartupListener implements FrameworkListener, SynchronousBundleListener {
+    private static final String SYSTEM_PROP_KARAF_CONSOLE_STARTED = 
"karaf.console.started";
+
+       private final BundleContext context;
+    StartupListener(BundleContext context) {
+        this.context = context;
+        context.addBundleListener(this);
+        context.addFrameworkListener(this);
+    }
+    public synchronized void bundleChanged(BundleEvent bundleEvent) {
+        Bundle[] bundles = context.getBundles();
+        int numActive = 0;
+        int numBundles = bundles.length;
+        for (Bundle bundle : bundles) {
+            if (bundle.getHeaders().get(Constants.FRAGMENT_HOST) != null) {
+                numBundles--;
+            } else if (bundle.getState() == Bundle.ACTIVE) {
+                numActive ++;
+            }
+        }
+        boolean started = 
Boolean.parseBoolean(System.getProperty(SYSTEM_PROP_KARAF_CONSOLE_STARTED, 
"false"));
+        if (!started) {
+            showProgressBar(numActive, numBundles);
+        }
+    }
+    public synchronized void frameworkEvent(FrameworkEvent frameworkEvent) {
+        if (frameworkEvent.getType() == FrameworkEvent.STARTLEVEL_CHANGED) {
+            int defStartLevel = 
Integer.parseInt(System.getProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL));
+            int startLevel = 
context.getBundle(0).adapt(FrameworkStartLevel.class).getStartLevel();
+            if (startLevel >= defStartLevel) {
+                context.removeBundleListener(this);
+                context.removeFrameworkListener(this);
+            }
+        }
+    }
+    public void showProgressBar(int done, int total) {
+        int percent = (done * 100) / total;
+        StringBuilder sb = new StringBuilder();
+        sb.append(String.format("\r%3d%% [", percent));
+        for (int i = 0; i < 100; i++) {
+            if (i < percent) {
+                sb.append('=');
+            } else if (i == percent) {
+                sb.append('>');
+            } else {
+                sb.append(' ');
+            }
+        }
+        sb.append(']');
+        System.out.print(sb.toString());
+        System.out.flush();
+        if (done == total) {
+            System.out.println();
+        }
+    }
+}
\ No newline at end of file

Added: 
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/impl/jline/DelayedStarted.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/impl/jline/DelayedStarted.java?rev=1369825&view=auto
==============================================================================
--- 
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/impl/jline/DelayedStarted.java
 (added)
+++ 
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/impl/jline/DelayedStarted.java
 Mon Aug  6 12:54:38 2012
@@ -0,0 +1,73 @@
+package org.apache.karaf.shell.console.impl.jline;
+
+import java.io.InputStream;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.startlevel.FrameworkStartLevel;
+
+/**
+ * Delay the start of the console until the desired start level is reached or 
enter is pressed
+ */
+class DelayedStarted extends Thread implements FrameworkListener {
+    private static final String SYSTEM_PROP_KARAF_CONSOLE_STARTED = 
"karaf.console.started";
+
+       private final AtomicBoolean started = new AtomicBoolean(false);
+    private final InputStream in;
+       private final Runnable console;
+       private final BundleContext bundleContext;
+
+    DelayedStarted(Runnable console, BundleContext bundleContext, InputStream 
in) {
+        super("Karaf Shell Console Thread");
+               this.console = console;
+               this.bundleContext = bundleContext;
+        this.in = in;
+        int defaultStartLevel = 
Integer.parseInt(System.getProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL));
+        int startLevel = 
bundleContext.getBundle(0).adapt(FrameworkStartLevel.class).getStartLevel();
+        if (startLevel >= defaultStartLevel) {
+            started.set(true);
+        } else {
+            bundleContext.addFrameworkListener(this);
+            frameworkEvent(new 
FrameworkEvent(FrameworkEvent.STARTLEVEL_CHANGED, bundleContext.getBundle(), 
null));
+        }
+    }
+
+    public void run() {
+        try {
+            while (!started.get()) {
+                if (in.available() == 0) {
+                    Thread.sleep(10);
+                }
+                while (in.available() > 0) {
+                    char ch = (char) in.read();
+                    if (ch == '\r' || ch == '\n') {
+                        started.set(true);
+                        break;
+                    }
+                }
+            }
+        } catch (Throwable t) {
+            // Ignore
+        }
+
+        // Signal to the main module that it can stop displaying the startup 
progress
+        System.setProperty(SYSTEM_PROP_KARAF_CONSOLE_STARTED, "true");
+
+        System.out.println();
+        this.bundleContext.removeFrameworkListener(this);
+        console.run();
+    }
+
+    public void frameworkEvent(FrameworkEvent event) {
+        if (event.getType() == FrameworkEvent.STARTLEVEL_CHANGED) {
+            int defaultStartLevel = 
Integer.parseInt(System.getProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL));
+            int startLevel = 
this.bundleContext.getBundle(0).adapt(FrameworkStartLevel.class).getStartLevel();
+            if (startLevel >= defaultStartLevel) {
+                started.set(true);
+            }
+        }
+    }
+}

Modified: 
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/impl/jline/LocalConsoleManager.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/impl/jline/LocalConsoleManager.java?rev=1369825&r1=1369824&r2=1369825&view=diff
==============================================================================
--- 
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/impl/jline/LocalConsoleManager.java
 (original)
+++ 
karaf/trunk/shell/console/src/main/java/org/apache/karaf/shell/console/impl/jline/LocalConsoleManager.java
 Mon Aug  6 12:54:38 2012
@@ -88,13 +88,13 @@ public class LocalConsoleManager {
         String agentId = startAgent("karaf");
         this.console = consoleFactory.createLocal(this.commandProcessor, 
terminal, callback);
         this.console.getSession().put(SshAgent.SSH_AUTHSOCKET_ENV_NAME, 
agentId);
-        BundleWatcher watcher = new BundleWatcher(bundleContext, 
defaultStartLevel, System.out, new Runnable() {
+        DelayedStarted watcher = new DelayedStarted(new Runnable() {
             
             @Override
             public void run() {
                 consoleFactory.startConsoleAs(console, subject);
             }
-        });
+        }, bundleContext, System.in);
         new Thread(watcher).start();
     }
 


Reply via email to