NIHVIVO-336 Improve the function of StartupManager and StartupStatus

This commit is contained in:
j2blake 2011-09-23 18:51:05 +00:00
parent 65bba272df
commit 0726b3280e
2 changed files with 110 additions and 16 deletions

View file

@ -18,7 +18,16 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* TODO
* Instantiate and run the ServletContextListeners for Vitro, while accumulating
* messages in StartupStatus.
*
* The startup listeners are stored in a file with one full-qualified class name
* per line. Blank lines and comment lines (starting with '#') are ignored.
*
* No exception in the listeners should prevent the successful completion.
* However, an uncaught exception or a fatal error status will cause the
* StartupStatusDisplayFilter to disply the problem instead of showing the home
* page (or any other requested page).
*/
public class StartupManager implements ServletContextListener {
private static final Log log = LogFactory.getLog(StartupManager.class);
@ -175,8 +184,11 @@ public class StartupManager implements ServletContextListener {
try {
log.debug("Initializing '" + listener.getClass().getName() + "'");
listener.contextInitialized(sce);
ss.listenerExecuted(listener);
} catch (Exception e) {
ss.fatal(listener, "Threw unexpected exception", e);
log.error("Listener threw fatal exception: '"
+ listener.getClass().getName() + "'", e);
}
}

View file

@ -2,6 +2,8 @@
package edu.cornell.mannlib.vitro.webapp.startup;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -10,11 +12,16 @@ import javax.servlet.ServletContext;
import javax.servlet.ServletContextListener;
/**
* TODO
* Accumulates a list of messages from the StartupManager, and from the context
* listeners that the run during startup.
*/
public class StartupStatus {
private static final String ATTRIBUTE_NAME = "STARTUP_STATUS";
// ----------------------------------------------------------------------
// static methods
// ----------------------------------------------------------------------
public static StartupStatus getBean(ServletContext ctx) {
StartupStatus ss;
@ -29,6 +36,10 @@ public class StartupStatus {
return ss;
}
// ----------------------------------------------------------------------
// methods to set status
// ----------------------------------------------------------------------
private List<StatusItem> itemList = new ArrayList<StatusItem>();
public void info(ServletContextListener listener, String message) {
@ -58,21 +69,22 @@ public class StartupStatus {
addItem(StatusItem.Level.FATAL, listener, message, cause);
}
/** Say that a previous fatal error prevented this listener from running. */
public void listenerNotExecuted(ServletContextListener listener) {
addItem(StatusItem.Level.NOT_EXECUTED, listener, "Not executed", null);
addItem(StatusItem.Level.NOT_EXECUTED,
listener,
"Not executed - startup was aborted by a previous fatal error.",
null);
}
public boolean isStartupAborted() {
/** Create a simple item for this listener if no other exists. */
public void listenerExecuted(ServletContextListener listener) {
for (StatusItem item : itemList) {
if (item.level == StatusItem.Level.FATAL) {
return true;
if (item.getSourceName().equals(listener.getClass().getName())) {
return;
}
}
return false;
}
public List<StatusItem> getStatusItems() {
return Collections.unmodifiableList(itemList);
addItem(StatusItem.Level.INFO, listener, "Ran successfully.", null);
}
private void addItem(StatusItem.Level level, ServletContextListener source,
@ -80,22 +92,92 @@ public class StartupStatus {
itemList.add(new StatusItem(level, source, message, cause));
}
// ----------------------------------------------------------------------
// methods to query status
// ----------------------------------------------------------------------
public boolean allClear() {
return getErrorItems().isEmpty() && getWarningItems().isEmpty();
}
public boolean isStartupAborted() {
return !getErrorItems().isEmpty();
}
public List<StatusItem> getStatusItems() {
return Collections.unmodifiableList(itemList);
}
public List<StatusItem> getErrorItems() {
List<StatusItem> list = new ArrayList<StartupStatus.StatusItem>();
for (StatusItem item : itemList) {
if (item.level == StatusItem.Level.FATAL) {
list.add(item);
}
}
return list;
}
public List<StatusItem> getWarningItems() {
List<StatusItem> list = new ArrayList<StartupStatus.StatusItem>();
for (StatusItem item : itemList) {
if (item.level == StatusItem.Level.WARNING) {
list.add(item);
}
}
return list;
}
// ----------------------------------------------------------------------
// helper classes
// ----------------------------------------------------------------------
public static class StatusItem {
public enum Level {
INFO, WARNING, FATAL, NOT_EXECUTED
}
final Level level;
final String sourceName;
final String message;
final Throwable cause;
private final Level level;
private final String sourceName;
private final String shortSourceName;
private final String message;
private final String cause;
public StatusItem(Level level, ServletContextListener source,
String message, Throwable cause) {
this.level = level;
this.sourceName = source.getClass().getName();
this.shortSourceName = source.getClass().getSimpleName();
this.message = message;
this.cause = cause;
if (cause == null) {
this.cause = "";
} else {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
cause.printStackTrace(pw);
this.cause = sw.toString();
}
}
public Level getLevel() {
return level;
}
public String getSourceName() {
return sourceName;
}
public String getShortSourceName() {
return shortSourceName;
}
public String getMessage() {
return message;
}
public String getCause() {
return cause;
}
}