--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/classes/hirondelle/web4j/StartupTasks.java Wed Dec 04 17:00:31 2013 +0100
@@ -0,0 +1,79 @@
+package hirondelle.web4j;
+
+import javax.servlet.ServletConfig;
+
+import hirondelle.web4j.model.AppException;
+import hirondelle.web4j.database.ConnectionSource;
+
+/**
+ Perform startup tasks.
+
+ <P>See {@link hirondelle.web4j.BuildImpl} for important information on how this item is configured.
+ {@link hirondelle.web4j.BuildImpl#forStartupTasks()}
+ returns the configured implementation of this interface.
+
+ <P>Allows the application programmer to perform any needed initialization tasks.
+
+ <P>These tasks are performed only once, upon startup (caveat below).
+ For example, the application may need to place items into application scope. Here's an example
+ <a href="http://www.javapractices.com/apps/fish/javadoc/src-html/hirondelle/web4j/config/Startup.html">implementation</a>
+ taken from an example application.
+
+ <P>
+ See {@link hirondelle.web4j.database.ConnectionSource#init(java.util.Map)}, for startup
+ tasks related to database connections.
+
+ <P>Startup tasks often depend on a database. If all of your databases are running when your app
+ starts up, then all startup tasks will be completed during start-up.
+
+ <P>However, sometimes a database may be down when your application starts up.
+ In that case, web4j will keep track of which databases are down. Later, when a request comes into its Controller,
+ it will re-test each offending database, to see if it's now running; when the database is seen to be running, then
+ web4j will then pass the name of the database to {@link #startApplication(ServletConfig, String)}.
+ (This processing takes place after startup, and thus, in a multi-threaded environment. The framework performs
+ the necessary external synchronization of this class.)
+*/
+public interface StartupTasks {
+
+ /**
+ Perform any startup tasks needed by the application.
+ <P>Possible tasks include:
+ <ul>
+ <li>disseminate values configured in <tt>web.xml</tt>
+ <li>place items into application scope, such as code tables read from the database
+ <li>set the default {@link java.util.TimeZone}
+ </ul>
+
+ <P>This method is called by WEB4J near the end of startup processing.
+ It's first called with an empty String for the database name; this is intended for any
+ tasks that may be unrelated to any database at all.
+ It's then called again, once for each database defined by {@link ConnectionSource#getDatabaseNames()} (in
+ the iteration order of the <tt>Set</tt> returned by that method).
+
+ <P>Example of a typical implementation:
+<pre>
+public void startApplication(ServletConfig aConfig, String aDbName) throws DAOException {
+ if (!Util.textHasContent(aDbName)){
+ //tasks not related to any db
+ }
+ else if (ConnectionSrc.DEFAULT.equals(aDbName)){
+ //tasks related to this db
+ }
+ else if (ConnectionSrc.TRANSLATION.equals(aDbName)){
+ //tasks related to this db
+ }
+}</pre>
+
+ <P>This method is called N+1 times by the framework, where N is the number of databases.
+ The framework has confirmed that the database is running before it calls this method.
+
+ @param aConfig is not a Map, as in other interfaces, since startup tasks
+ often need more than just settings in <tt>web.xml</tt> - for example, placing code tables in app scope will
+ need access to the <tt>ServletContext</tt>.
+ @param aDatabaseName refers to one of the names defined by {@link ConnectionSource#getDatabaseNames()},
+ or an empty string. Implementations of this method should reference those names directly, instead of
+ hard-coding strings.
+ */
+ void startApplication(ServletConfig aConfig, String aDatabaseName) throws AppException;
+
+}