001: package dalma;
002:
003: import java.util.logging.Logger;
004:
005: /**
006: * Entry point of the user-implemented workflow application.
007: *
008: * <p>
009: * A workflow application that runs inside the dalma container
010: * needs to have a class that derives from this class. Such class
011: * serves as the entry point to the workflow program, and its fully-qualified
012: * class name must be <tt>Main</tt> (in the root package.)
013: *
014: * <h3>Configuring Program</h3>
015: * <p>
016: * A {@link Program} typically needs to be configured with environment-specific
017: * information to function. For example, perhaps a program is some kind of e-mail
018: * automation system and may use 2 e-mail endpoints and 1 IRC endpoint.
019: *
020: * A {@link Program} communicates these configuration requirements to the container
021: * by using {@link Resource} annotation. In the above example, the {@link Program}
022: * would be written something like:
023: *
024: * <pre>
025: * class Main extends dalma.Program {
026: * @Resource
027: * public EmailEndPoint externalMail;
028: *
029: * @Resource
030: * public EmailEndPoint maintananceMail;
031: *
032: * @Resource
033: * public IRCEndPoint chatEndPoint;
034: *
035: * @Resource
036: * public String greetingMessage;
037: *
038: * ...
039: * }
040: * </pre>
041: *
042: * <p>
043: * At runtime, the container invokes setters and sets fields to "inject" references
044: * into the program before the {@link #init(Engine)} method
045: * is invoked.
046: *
047: * @author Kohsuke Kawaguchi
048: */
049: public abstract class Program {
050: /**
051: * Called right after the {@link Engine} instance is created
052: * and populated with the configured endpoints.
053: *
054: * <p>
055: * This callback can be used to further configure endpoints,
056: * for example by installing listeners and etc.
057: *
058: * <p>
059: * In rare case, when a {@link Program} doesn't know statically
060: * what endpoints it wants to use,
061: * this callback can be also used to add additional endpoints
062: * programatically if desired.
063: *
064: * <p>
065: * Note that if kinds and endpoints are known statically,
066: * then the {@link Program}-derived class can use a resource injection
067: * to get access to those endpoints.
068: *
069: * @throws Exception
070: * Any exception thrown by this method is considered to indicate
071: * an error, and prevents the {@link Program} from running.
072: */
073: public void init(Engine engine) throws Exception {
074: // noop
075: }
076:
077: /**
078: * Called after the {@link Engine} is {@link Engine#start()} started.
079: *
080: * <p>
081: * In rare case, when a {@link Program} wants to start a new
082: * {@link Conversation} proactively, it can use this callback to do so.
083: *
084: * @throws Exception
085: * Any exception thrown by this method is considered to indicate
086: * an error, and prevents the {@link Program} from running.
087: */
088: public void main(Engine engine) throws Exception {
089: // noop
090: }
091:
092: /**
093: * Called right before the application is shut down,
094: * to perform any optional clean up.
095: *
096: * @throws Exception
097: * Any exception thrown by this method is recorded
098: * but otherwise the shut down operation continues regardless.
099: */
100: public void cleanup(Engine engine) throws Exception {
101:
102: }
103:
104: // start with the default logger instance so that the user program
105: // can start using it even within the constructor.
106: // we'll replace this with a real logger at some later stage
107: // of initialization
108: private Logger logger = Logger.getLogger(Program.class.getName());
109:
110: /**
111: * Gets the logger for this workflow application.
112: *
113: * <p>
114: * Logs recorded by this logger will be made available
115: * to the monitoring/management applications.
116: *
117: * @return
118: * always non-null.
119: */
120: public Logger getLogger() {
121: return logger;
122: }
123:
124: /**
125: * Reserved for the container. Do not invoke this method.
126: */
127: public void setLogger(Logger logger) {
128: this.logger = logger;
129: }
130: }
|