Make StartupStatus thread-safe, so we can add items at any time.
This commit is contained in:
parent
7439e02964
commit
350faa50fa
1 changed files with 84 additions and 22 deletions
|
@ -5,7 +5,6 @@ package edu.cornell.mannlib.vitro.webapp.startup;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
|
@ -17,6 +16,9 @@ import org.apache.commons.logging.LogFactory;
|
||||||
/**
|
/**
|
||||||
* Accumulates a list of messages from the StartupManager, and from the context
|
* Accumulates a list of messages from the StartupManager, and from the context
|
||||||
* listeners that the run during startup.
|
* listeners that the run during startup.
|
||||||
|
*
|
||||||
|
* This is thread-safe, with immutable items in the list and synchronized access
|
||||||
|
* to the list.
|
||||||
*/
|
*/
|
||||||
public class StartupStatus {
|
public class StartupStatus {
|
||||||
private static final Log log = LogFactory.getLog(StartupStatus.class);
|
private static final Log log = LogFactory.getLog(StartupStatus.class);
|
||||||
|
@ -45,7 +47,7 @@ public class StartupStatus {
|
||||||
// methods to set status - note that these write to the log also.
|
// methods to set status - note that these write to the log also.
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
private List<StatusItem> itemList = new ArrayList<StatusItem>();
|
private SynchronizedStatusItemList itemList = new SynchronizedStatusItemList();
|
||||||
|
|
||||||
public void info(ServletContextListener listener, String message) {
|
public void info(ServletContextListener listener, String message) {
|
||||||
addItem(StatusItem.Level.INFO, listener, message, null);
|
addItem(StatusItem.Level.INFO, listener, message, null);
|
||||||
|
@ -84,13 +86,11 @@ public class StartupStatus {
|
||||||
|
|
||||||
/** Create a simple item for this listener if no other exists. */
|
/** Create a simple item for this listener if no other exists. */
|
||||||
public void listenerExecuted(ServletContextListener listener) {
|
public void listenerExecuted(ServletContextListener listener) {
|
||||||
for (StatusItem item : itemList) {
|
List<StatusItem> itemsForThisListener = getItemsForListener(listener);
|
||||||
if (item.getSourceName().equals(listener.getClass().getName())) {
|
if (itemsForThisListener.isEmpty()) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addItem(StatusItem.Level.INFO, listener, "Ran successfully.", null);
|
addItem(StatusItem.Level.INFO, listener, "Ran successfully.", null);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void addItem(StatusItem.Level level, ServletContextListener source,
|
private void addItem(StatusItem.Level level, ServletContextListener source,
|
||||||
String message, Throwable cause) {
|
String message, Throwable cause) {
|
||||||
|
@ -133,33 +133,29 @@ public class StartupStatus {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<StatusItem> getStatusItems() {
|
public List<StatusItem> getStatusItems() {
|
||||||
return Collections.unmodifiableList(itemList);
|
return itemList.filterItems(StatusItemFilter.ALL_ITEMS_FILTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<StatusItem> getErrorItems() {
|
public List<StatusItem> getErrorItems() {
|
||||||
List<StatusItem> list = new ArrayList<StartupStatus.StatusItem>();
|
return itemList.filterItems(StatusItemFilter.ERROR_ITEMS_FILTER);
|
||||||
for (StatusItem item : itemList) {
|
|
||||||
if (item.level == StatusItem.Level.FATAL) {
|
|
||||||
list.add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<StatusItem> getWarningItems() {
|
public List<StatusItem> getWarningItems() {
|
||||||
List<StatusItem> list = new ArrayList<StartupStatus.StatusItem>();
|
return itemList.filterItems(StatusItemFilter.WARNING_ITEMS_FILTER);
|
||||||
for (StatusItem item : itemList) {
|
|
||||||
if (item.level == StatusItem.Level.WARNING) {
|
|
||||||
list.add(item);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return list;
|
public List<StatusItem> getItemsForListener(ServletContextListener listener) {
|
||||||
|
return itemList.filterItems(StatusItemFilter.listenerFilter(listener));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// helper classes
|
// helper classes
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An immutable item that can't throw an exception during construction and
|
||||||
|
* will always contain suitable, non-null values.
|
||||||
|
*/
|
||||||
public static class StatusItem {
|
public static class StatusItem {
|
||||||
public enum Level {
|
public enum Level {
|
||||||
INFO, WARNING, FATAL, NOT_EXECUTED
|
INFO, WARNING, FATAL, NOT_EXECUTED
|
||||||
|
@ -257,4 +253,70 @@ public class StartupStatus {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A filter class and some basic instances.
|
||||||
|
*/
|
||||||
|
private static abstract class StatusItemFilter {
|
||||||
|
public abstract boolean accept(StatusItem item);
|
||||||
|
|
||||||
|
public static final StatusItemFilter ALL_ITEMS_FILTER = new StatusItemFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(StatusItem item) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final StatusItemFilter ERROR_ITEMS_FILTER = new StatusItemFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(StatusItem item) {
|
||||||
|
return item.level == StatusItem.Level.FATAL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final StatusItemFilter WARNING_ITEMS_FILTER = new StatusItemFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(StatusItem item) {
|
||||||
|
return item.level == StatusItem.Level.WARNING;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static StatusItemFilter listenerFilter(
|
||||||
|
ServletContextListener listener) {
|
||||||
|
final String listenerName = listener.getClass().getName();
|
||||||
|
|
||||||
|
return new StatusItemFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(StatusItem item) {
|
||||||
|
return item.getSourceName().equals(listenerName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list, with synchronized methods for adding to it, and for getting a
|
||||||
|
* filtered subset of it.
|
||||||
|
*/
|
||||||
|
private class SynchronizedStatusItemList {
|
||||||
|
private final List<StatusItem> list = new ArrayList<StatusItem>();
|
||||||
|
|
||||||
|
public void add(StatusItem item) {
|
||||||
|
synchronized (list) {
|
||||||
|
list.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<StatusItem> filterItems(StatusItemFilter filter) {
|
||||||
|
List<StatusItem> filteredList = new ArrayList<StatusItem>();
|
||||||
|
synchronized (list) {
|
||||||
|
for (StatusItem item : list) {
|
||||||
|
if (filter.accept(item)) {
|
||||||
|
filteredList.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filteredList;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue