View Javadoc

1   /*
2    * $Id: RequestContext.java 19191 2010-08-25 21:05:23Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule;
12  
13  import org.mule.api.ExceptionPayload;
14  import org.mule.api.MuleEvent;
15  import org.mule.api.MuleEventContext;
16  import org.mule.api.MuleMessage;
17  import org.mule.api.ThreadSafeAccess;
18  import org.mule.api.endpoint.ImmutableEndpoint;
19  import org.mule.api.endpoint.OutboundEndpoint;
20  import org.mule.api.processor.MessageProcessor;
21  
22  /**
23   * <code>RequestContext</code> is a thread context where components can get the
24   * current event or set response properties that will be sent on the outgoing
25   * message.
26   *
27   * <p>RequestContext seems to be used to allow thread local mutation of events that
28   * are not otherwise available in the scope.  so this is a good place to create a new
29   * thread local copy - it will be read because supporting code is expecting mutation.</p>
30   *
31   */
32  public final class RequestContext
33  {
34      // to clarify "safe" in constructors
35      public static final boolean SAFE = true;
36      public static final boolean UNSAFE = true;
37  
38      // setting this to false gives old (mutable) semantics in non-critical cases
39      private static final boolean DEFAULT_ACTION = SAFE;
40  
41      private static final ThreadLocal currentEvent = new ThreadLocal();
42  
43      /** Do not instanciate. */
44      protected RequestContext()
45      {
46          // no-op
47      }
48  
49      public static MuleEventContext getEventContext()
50      {
51          MuleEvent event = getEvent();
52          if (event != null)
53          {
54              return new DefaultMuleEventContext(event);
55          }
56          else
57          {
58              return null;
59          }
60      }
61  
62      public static MuleEvent getEvent()
63      {
64          return (MuleEvent) currentEvent.get();
65      }
66  
67      /**
68       * Set an event for out-of-scope thread access.  Safe: use by default
69       *
70       * @param event - the event to set
71       * @return A new mutable copy of the event set
72       */
73      public static MuleEvent setEvent(MuleEvent event)
74      {
75          return internalSetEvent(newEvent(event, DEFAULT_ACTION));
76      }
77  
78      protected static MuleEvent internalSetEvent(MuleEvent event)
79      {
80          currentEvent.set(event);
81          return event;
82      }
83  
84      protected static MuleMessage internalRewriteEvent(MuleMessage message, boolean safe)
85      {
86          if (message != null)
87          {
88              MuleEvent event = getEvent();
89              if (event != null)
90              {
91                  MuleMessage copy = newMessage(message, safe);
92                  MuleEvent newEvent = new DefaultMuleEvent(copy, event);
93                  if (safe)
94                  {
95                      resetAccessControl(copy);
96                  }
97                  internalSetEvent(newEvent);
98                  return copy;
99              }
100         }
101         return message;
102     }
103 
104     /**
105      * Resets the current request context (clears all information).
106      */
107     public static void clear()
108     {
109         setEvent(null);
110     }
111 
112     /**
113      * There is no unsafe version of this because it shouldn't be performance critical
114      *
115      * @param exceptionPayload
116      */
117     public static void setExceptionPayload(ExceptionPayload exceptionPayload)
118     {
119         MuleEvent newEvent = newEvent(getEvent(), SAFE);
120         newEvent.getMessage().setExceptionPayload(exceptionPayload);
121         internalSetEvent(newEvent);
122     }
123 
124     public static ExceptionPayload getExceptionPayload()
125     {
126         return getEvent().getMessage().getExceptionPayload();
127     }
128 
129     public static MuleMessage safeMessageCopy(MuleMessage message)
130     {
131         return newMessage(message, SAFE);
132     }
133 
134     public static MuleEvent cloneAndUpdateEventEndpoint(MuleEvent event, MessageProcessor target)
135     {
136         return updateEventEndpoint(newEvent(event, SAFE), target);
137     }
138     
139     public static MuleEvent updateEventEndpoint(MuleEvent event, MessageProcessor target)
140     {
141         if (target instanceof OutboundEndpoint)
142         {
143             return new DefaultMuleEvent(event.getMessage(), (ImmutableEndpoint) target, event.getSession());
144         }
145         else
146         {
147             return event;
148         }
149     }
150 
151     protected static MuleEvent newEvent(MuleEvent event, boolean safe)
152     {
153         if (safe && event instanceof ThreadSafeAccess)
154         {
155             return (MuleEvent) ((ThreadSafeAccess)event).newThreadCopy();
156         }
157         else
158         {
159             return event;
160         }
161     }
162 
163     protected static MuleMessage newMessage(MuleMessage message, boolean safe)
164     {
165         if (safe && message instanceof ThreadSafeAccess)
166         {
167             return (MuleMessage) ((ThreadSafeAccess)message).newThreadCopy();
168         }
169         else
170         {
171             return message;
172         }
173     }
174 
175     protected static void resetAccessControl(Object object)
176     {
177         if (object instanceof ThreadSafeAccess)
178         {
179             ((ThreadSafeAccess) object).resetAccessControl();
180         }
181     }
182 
183 }