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();
}