001 package org.apache.geronimo.system.main;
002
003 import java.io.PrintStream;
004
005 import org.apache.geronimo.kernel.Kernel;
006 import org.apache.geronimo.kernel.repository.Artifact;
007 import java.text.DateFormat;
008 import java.text.SimpleDateFormat;
009 import java.util.TimeZone;
010 import java.util.Date;
011
012 /**
013 * A startup monitor that shows the progress of loading and starting
014 * modules, outputing a new line for each module started
015 * showing the time taken to start the module along with the
016 * moduleId.
017 * <p/>
018 * This startup monitor produces more lines of output than the
019 * ProgressBarStartupMonitor but its output is suitable for redirection
020 * to a file or for when Geronimo is running under an IDE or other tool.
021 * <p/>
022 * A summary will also be produced containing a list of ports
023 * Geronimo is listening on, the configIds of application modules
024 * that were started and the URLs of Web applications that were started.
025 *
026 * @version $Revision: 1.0$
027 */
028 public class LongStartupMonitor implements StartupMonitor {
029
030 /**
031 * PrintStream
032 */
033 private PrintStream out;
034
035 /**
036 * Number of modules to start
037 */
038 private int numModules;
039
040 /**
041 * Number of digits in number of modules to start
042 */
043 private int numModulesDigits;
044
045 /**
046 * Number of modules currently being started
047 */
048 private int moduleNum;
049
050 /**
051 * Length of longest module name
052 */
053 private int longestModuleNameLength;
054
055 /**
056 * Time Geronimo was started
057 */
058 private long started;
059
060 /**
061 * Time the current module being processed was started
062 */
063 private long moduleStarted;
064
065 /**
066 * The Kernel of the system being started
067 */
068 private Kernel kernel;
069
070 public synchronized void systemStarting(long startTime) {
071 out = System.out;
072 started = startTime;
073 }
074
075 public synchronized void systemStarted(Kernel kernel) {
076 this.kernel = kernel;
077 }
078
079 public synchronized void foundModules(Artifact[] modules) {
080 numModules = modules.length;
081 numModulesDigits = Integer.toString(numModules).length();
082
083 for (int i = 0, len= 0; i < modules.length; i++) {
084 len = modules[i].toString().length();
085 if (len > longestModuleNameLength)
086 longestModuleNameLength = len;
087 }
088 }
089
090 public synchronized void moduleLoading(Artifact module) {
091 StringBuffer buf = new StringBuffer("Module ");
092 // pad module index
093 int configIndexDigits = Integer.toString(++moduleNum).length();
094 for (; configIndexDigits < numModulesDigits; configIndexDigits++) {
095 buf.append(' ');
096 }
097 // append module index / total configs
098 buf.append(moduleNum).append('/').append(numModules).append(' ');
099 // append module name
100 buf.append(module);
101 // pad end of module with spaces so trailing startup times will line up
102 int len = module.toString().length();
103 for (; len < longestModuleNameLength; len++) {
104 buf.append(' ');
105 }
106 out.print(buf);
107 }
108
109 public synchronized void moduleLoaded(Artifact module) {
110 }
111
112 public synchronized void moduleStarting(Artifact module) {
113 moduleStarted = System.currentTimeMillis();
114 }
115
116 public synchronized void moduleStarted(Artifact module) {
117 long time = System.currentTimeMillis() - moduleStarted;
118 StringBuffer buf = new StringBuffer();
119 buf.append(" started in ");
120
121 String formattedTime = getFormattedTime(time);
122 if (formattedTime.startsWith("0.")) {
123 // don't display zero seconds
124 formattedTime = " " +formattedTime.substring(1);
125 }
126
127 // if first number (e.g. seconds or minutes) is one digit,
128 // pad it with a leading space to get times to line up nicely
129 int index = formattedTime.indexOf(':'); // must look for colon first
130 if (index == -1)
131 index = formattedTime.indexOf('.');
132
133 if (index == 1)
134 buf.append(' ');
135
136 buf.append(formattedTime);
137
138 out.println(buf.toString());
139 }
140
141 public synchronized void startupFinished() {
142 int time = Math.round((float) (System.currentTimeMillis() - started) / 1000f);
143
144 out.println("Startup completed in " + time + " seconds");
145 StartupMonitorUtil.wrapUp(out, kernel);
146 }
147
148 public synchronized void serverStartFailed(Exception problem) {
149 out.println("Server Startup failed");
150 out.println();
151 problem.printStackTrace(out);
152 }
153
154 // time formatting method - thanks to Maven
155 private static String getFormattedTime( long time )
156 {
157 String pattern = "s.SSS's'";
158 if ( time / 60000L > 0 )
159 {
160 pattern = "m:s" + pattern;
161 if ( time / 3600000L > 0 )
162 {
163 pattern = "H:m" + pattern;
164 }
165 }
166 DateFormat fmt = new SimpleDateFormat( pattern );
167 fmt.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
168 return fmt.format( new Date( time ) );
169 }
170 }