001: /*
002: * $Id: RequestContext.java 10489 2008-01-23 17:53:38Z dfeist $
003: * --------------------------------------------------------------------------------------
004: * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
005: *
006: * The software in this package is published under the terms of the CPAL v1.0
007: * license, a copy of which has been included with this distribution in the
008: * LICENSE.txt file.
009: */
010:
011: package org.mule;
012:
013: import org.mule.api.ExceptionPayload;
014: import org.mule.api.MuleEvent;
015: import org.mule.api.MuleEventContext;
016: import org.mule.api.MuleMessage;
017: import org.mule.api.ThreadSafeAccess;
018:
019: /**
020: * <code>RequestContext</code> is a thread context where components can get the
021: * current event or set response properties that will be sent on the outgoing
022: * message.
023: *
024: * <p>RequestContext seems to be used to allow thread local mutation of events that
025: * are not otherwise available in the scope. so this is a good place to create a new
026: * thread local copy - it will be read because supporting code is expecting mutation.</p>
027: *
028: */
029: public final class RequestContext {
030: // to clarify "safe" in constructors
031: public static boolean SAFE = true;
032: public static boolean UNSAFE = true;
033:
034: // setting this to false gives old (mutable) semantics in non-critical cases
035: private static boolean DEFAULT_ACTION = SAFE;
036:
037: private static final ThreadLocal currentEvent = new ThreadLocal();
038:
039: /** Do not instanciate. */
040: protected RequestContext() {
041: // no-op
042: }
043:
044: public static MuleEventContext getEventContext() {
045: MuleEvent event = getEvent();
046: if (event != null) {
047: return new DefaultMuleEventContext(event);
048: } else {
049: return null;
050: }
051: }
052:
053: public static MuleEvent getEvent() {
054: return (MuleEvent) currentEvent.get();
055: }
056:
057: /**
058: * Set an event for out-of-scope thread access. Safe: use by default
059: *
060: * @param event - the event to set
061: * @return A new mutable copy of the event set
062: */
063: public static MuleEvent setEvent(MuleEvent event) {
064: return internalSetEvent(newEvent(event, DEFAULT_ACTION));
065: }
066:
067: protected static MuleEvent internalSetEvent(MuleEvent event) {
068: currentEvent.set(event);
069: return event;
070: }
071:
072: protected static MuleMessage internalRewriteEvent(
073: MuleMessage message, boolean safe) {
074: if (message != null) {
075: MuleEvent event = getEvent();
076: if (event != null) {
077: MuleMessage copy = newMessage(message, safe);
078: MuleEvent newEvent = new DefaultMuleEvent(copy, event);
079: if (safe) {
080: resetAccessControl(copy);
081: }
082: internalSetEvent(newEvent);
083: return copy;
084: }
085: }
086: return message;
087: }
088:
089: /**
090: * Resets the current request context (clears all information).
091: */
092: public static void clear() {
093: setEvent(null);
094: }
095:
096: /**
097: * There is no unsafe version of this because it shouldn't be performance critical
098: *
099: * @param exceptionPayload
100: */
101: public static void setExceptionPayload(
102: ExceptionPayload exceptionPayload) {
103: MuleEvent newEvent = newEvent(getEvent(), SAFE);
104: newEvent.getMessage().setExceptionPayload(exceptionPayload);
105: internalSetEvent(newEvent);
106: }
107:
108: public static ExceptionPayload getExceptionPayload() {
109: return getEvent().getMessage().getExceptionPayload();
110: }
111:
112: public static MuleMessage safeMessageCopy(MuleMessage message) {
113: return newMessage(message, SAFE);
114: }
115:
116: protected static MuleEvent newEvent(MuleEvent event, boolean safe) {
117: if (safe && event instanceof ThreadSafeAccess) {
118: return (MuleEvent) ((ThreadSafeAccess) event)
119: .newThreadCopy();
120: } else {
121: return event;
122: }
123: }
124:
125: protected static MuleMessage newMessage(MuleMessage message,
126: boolean safe) {
127: if (safe && message instanceof ThreadSafeAccess) {
128: return (MuleMessage) ((ThreadSafeAccess) message)
129: .newThreadCopy();
130: } else {
131: return message;
132: }
133: }
134:
135: protected static void resetAccessControl(Object object) {
136: if (object instanceof ThreadSafeAccess) {
137: ((ThreadSafeAccess) object).resetAccessControl();
138: }
139: }
140:
141: }
|