001: /*--
002:
003: Copyright (C) 2002-2005 Adrian Price.
004: All rights reserved.
005:
006: Redistribution and use in source and binary forms, with or without
007: modification, are permitted provided that the following conditions
008: are met:
009:
010: 1. Redistributions of source code must retain the above copyright
011: notice, this list of conditions, and the following disclaimer.
012:
013: 2. Redistributions in binary form must reproduce the above copyright
014: notice, this list of conditions, and the disclaimer that follows
015: these conditions in the documentation and/or other materials
016: provided with the distribution.
017:
018: 3. The names "OBE" and "Open Business Engine" must not be used to
019: endorse or promote products derived from this software without prior
020: written permission. For written permission, please contact
021: adrianprice@sourceforge.net.
022:
023: 4. Products derived from this software may not be called "OBE" or
024: "Open Business Engine", nor may "OBE" or "Open Business Engine"
025: appear in their name, without prior written permission from
026: Adrian Price (adrianprice@users.sourceforge.net).
027:
028: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
029: WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
030: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
031: DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
032: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
033: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
034: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
035: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
036: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
037: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
038: POSSIBILITY OF SUCH DAMAGE.
039:
040: For more information on OBE, please see
041: <http://obe.sourceforge.net/>.
042:
043: */
044:
045: package org.obe.spi.event;
046:
047: import org.obe.engine.EngineContext;
048: import org.obe.spi.service.ApplicationEventBroker;
049:
050: import java.io.Serializable;
051: import java.util.*;
052:
053: /**
054: * Delivers an external event from a third party application or source. This
055: * is OBE's primary asynchronous integration mechanism.
056: *
057: * @author Adrian Price
058: * @see ApplicationEventBroker
059: * @see ApplicationEventListener
060: */
061: public class ApplicationEvent extends EventObject {
062: private static final long serialVersionUID = 2966489532857498559L;
063: public static final String CONTENT_TYPE = "ContentType";
064: public static final String SCHEMA = "Schema";
065: public static final String ACTION = "Action";
066: public static final String TIMEOUT_EVENT = "Timeout";
067: public static final String EXCEPTION_EVENT = "Exception";
068: protected static final Map EMPTY_MAP = Collections.EMPTY_MAP;
069: protected static final Serializable[] EMPTY_KEYS = {};
070:
071: private final String _contentType;
072: private final String _schema;
073: private final Map _properties;
074: private String _eventType;
075: private Serializable[] _keys;
076: private transient Object _application;
077: private Date _expiry;
078:
079: /**
080: * Constructs an application event object.
081: *
082: * @param source The source object on which the event occurred.
083: * @param contentType The MIME content type of the <code>source</code>
084: * object. Cannot be <code>null</code>.
085: * @param schema The schema for the <code>source</code> object. Cannot be
086: * <code>null</code>.
087: * @param properties Additional properties describing the event. Optional.
088: */
089: public ApplicationEvent(Object source, String contentType,
090: String schema, Map properties) {
091:
092: super (source);
093: if (contentType == null || schema == null)
094: throw new IllegalArgumentException(
095: "argument cannot be null");
096:
097: _contentType = contentType;
098: _schema = schema;
099: _properties = properties != null ? properties : EMPTY_MAP;
100: }
101:
102: /**
103: * Constructs an application event object.
104: *
105: * @param applicationContext An arbitrary application context.
106: * @param source The source object on which the event occurred.
107: * @param eventType The event type, as registered in the
108: * {@link ApplicationEventBroker}. Cannot be <code>null</code>.
109: * @param keys The key values, calculated from the <code>source</code>
110: * object according to the definition for <code>id</code>.
111: * @param contentType The MIME content type of the <code>source</code>
112: * object. Cannot be <code>null</code>.
113: * @param schema The schema for the <code>source</code> object. Cannot be
114: * <code>null</code>.
115: * @param properties Additional properties describing the event.
116: * @param expiration The date/time at which this event expires: the system
117: * will remove the event from storage at that time. If <code>null</code>,
118: */
119: public ApplicationEvent(Object applicationContext, Object source,
120: String eventType, Serializable[] keys, String contentType,
121: String schema, Map properties, Date expiration) {
122:
123: super (source);
124:
125: // Certain fields are mandatory.
126: if (eventType == null || contentType == null || schema == null)
127: throw new IllegalArgumentException(
128: "argument cannot be null");
129:
130: _contentType = contentType;
131: _schema = schema;
132: _eventType = eventType;
133: _application = applicationContext;
134: _keys = keys != null ? keys : EMPTY_KEYS;
135: _properties = properties != null ? properties : EMPTY_MAP;
136: _expiry = expiration;
137: }
138:
139: /**
140: * Returns the name of the JAF command which raised this event.
141: *
142: * @return JAF command name, <code>null</code> indicates the default
143: * command.
144: */
145: public String getAction() {
146: return (String) _properties.get(ACTION);
147: }
148:
149: /**
150: * Returns the MIME content type of the event data. The
151: * <a href="http://www.iana.org/assignments/media-types/">
152: * content type</a> indicates the type of object in the payload. For
153: * example, an XML document would have a content type of
154: * <code>text/xml</code>; an MS-Word document would be
155: * <code>application/msword</code>, a Java object would use the extension
156: * type <code>application/x-java-object</code>, and so on.
157: *
158: * @return The MIME content type.
159: * @see #getSchema
160: */
161: public String getContentType() {
162: return _contentType;
163: }
164:
165: /**
166: * Returns the business name for the application event. This must have been
167: * registered in the application event broker by a prior call to
168: * {@link ApplicationEventBroker#createEventType}.
169: *
170: * @return The event type.
171: */
172: public String getEventType() {
173: return _eventType;
174: }
175:
176: /**
177: * Sets the event type.
178: *
179: * @param eventType Event type. Must be a valid business event type as
180: * registered in the {@link ApplicationEventBroker}.
181: * @throws IllegalArgumentException if eventType is <code>null</code>.
182: */
183: public void setEventType(String eventType) {
184: if (eventType == null)
185: throw new IllegalArgumentException(
186: "eventType cannot be null");
187: _eventType = eventType;
188: }
189:
190: /**
191: * The name of the abstract schema for the payload (the source object). The
192: * interpretation depends on the content type. For example, the schema for a
193: * content type of <code>text/xml</code> would be the URI of the schema
194: * location or the Public or System ID of its DTD; if these are undefined,
195: * the tag name of the document element. The schema for a Java object is
196: * simply its fully qualified class name, or possibly the name of an
197: * interface that it implements.
198: *
199: * @return The abstract schema name.
200: * @see #getContentType
201: */
202: public String getSchema() {
203: return _schema;
204: }
205:
206: /**
207: * Returns the key values for the payload. The application event broker
208: * calculates the key values from the payload by evaluating the key value
209: * expressions in the event type definition.
210: *
211: * @return Key values for the payload.
212: */
213: public Serializable[] getKeys() {
214: return _keys.length == 0 ? _keys : (Serializable[]) _keys
215: .clone();
216: }
217:
218: /**
219: * Sets the keys for the payload.
220: *
221: * @param keys Event keys.
222: */
223: public void setKeys(Serializable[] keys) {
224: _keys = keys;
225: }
226:
227: /**
228: * Returns a custom attribute associated with the payload. Custom
229: * attributes provide additional metadata about the payload.
230: *
231: * @param key The attribute name.
232: * @return The attribute value, if defined.
233: */
234: public Object getProperty(String key) {
235: return _properties.get(key);
236: }
237:
238: /**
239: * Returns a map of all custom attributes associated with the payload.
240: *
241: * @return Attribute map, keyed on attribute name.
242: * @see #getProperty
243: */
244: public Map getProperties() {
245: return _properties;
246: }
247:
248: /**
249: * Returns the application context. This object is accessible through the
250: * {@link EngineContext#getApplication()} method.
251: *
252: * @return Application context.
253: */
254: public Object getApplication() {
255: return _application;
256: }
257:
258: /**
259: * Sets the application context.
260: *
261: * @param application The application context.
262: */
263: public void setApplication(Object application) {
264: _application = application;
265: }
266:
267: /**
268: * Returns the expiry date for the event.
269: *
270: * @return The expiry date.
271: */
272: public Date getExpiry() {
273: return _expiry;
274: }
275:
276: /**
277: * Sets the expiry date for the event.
278: *
279: * @param expiry Expiry date or <code>null</code> if the event should not
280: * be stored for subsequent consumption.
281: */
282: public void setExpiry(Date expiry) {
283: _expiry = expiry;
284: }
285:
286: public String toString() {
287: return "ApplicationEvent[id='"
288: + _eventType
289: + "', source="
290: + getSource()
291: + ", contentType='"
292: + _contentType
293: + "', schema='"
294: + _schema
295: + "', keys="
296: + (_keys == null ? null : "length:" + _keys.length
297: + Arrays.asList(_keys))
298: + ", properties="
299: + (_properties == null ? null : "size:"
300: + _properties.size() + _properties)
301: + ", expiry=" + _expiry + ']';
302: }
303: }
|