View Javadoc

1   /*
2    * $Id: RequestContext.java 20875 2011-01-04 16:09:25Z aperepel $
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  
19  /**
20   * <code>RequestContext</code> is a thread context where components can get the
21   * current event or set response properties that will be sent on the outgoing
22   * message.
23   *
24   * <p>RequestContext seems to be used to allow thread local mutation of events that
25   * are not otherwise available in the scope.  so this is a good place to create a new
26   * thread local copy - it will be read because supporting code is expecting mutation.</p>
27   *
28   */
29  public final class RequestContext
30  {
31      // to clarify "safe" in constructors
32      public static final boolean SAFE = true;
33      public static final boolean UNSAFE = true;
34  
35      // setting this to false gives old (mutable) semantics in non-critical cases
36      private static final boolean DEFAULT_ACTION = SAFE;
37  
38      private static final ThreadLocal currentEvent = new ThreadLocal();
39  
40      /** Do not instanciate. */
41      protected RequestContext()
42      {
43          // no-op
44      }
45  
46      public static MuleEventContext getEventContext()
47      {
48          MuleEvent event = getEvent();
49          if (event != null)
50          {
51              return new DefaultMuleEventContext(event);
52          }
53          else
54          {
55              return null;
56          }
57      }
58  
59      public static MuleEvent getEvent()
60      {
61          return (MuleEvent) currentEvent.get();
62      }
63  
64      /**
65       * Set an event for out-of-scope thread access.  Safe: use by default
66       *
67       * @param event - the event to set
68       * @return A new mutable copy of the event set
69       */
70      public static MuleEvent setEvent(MuleEvent event)
71      {
72          return internalSetEvent(newEvent(event, DEFAULT_ACTION));
73      }
74  
75      protected static MuleEvent internalSetEvent(MuleEvent event)
76      {
77          currentEvent.set(event);
78          return event;
79      }
80  
81      protected static MuleMessage internalRewriteEvent(MuleMessage message, boolean safe)
82      {
83          if (message != null)
84          {
85              MuleEvent event = getEvent();
86              if (event != null)
87              {
88                  MuleMessage copy = newMessage(message, safe);
89                  MuleEvent newEvent = new DefaultMuleEvent(copy, event);
90                  if (safe)
91                  {
92                      resetAccessControl(copy);
93                  }
94                  internalSetEvent(newEvent);
95                  return copy;
96              }
97          }
98          return message;
99      }
100 
101     /**
102      * Resets the current request context (clears all information).
103      */
104     public static void clear()
105     {
106         setEvent(null);
107     }
108 
109     /**
110      * There is no unsafe version of this because it shouldn't be performance critical
111      *
112      * @param exceptionPayload
113      */
114     public static void setExceptionPayload(ExceptionPayload exceptionPayload)
115     {
116         MuleEvent newEvent = newEvent(getEvent(), SAFE);
117         newEvent.getMessage().setExceptionPayload(exceptionPayload);
118         internalSetEvent(newEvent);
119     }
120 
121     public static ExceptionPayload getExceptionPayload()
122     {
123         return getEvent().getMessage().getExceptionPayload();
124     }
125 
126     public static MuleMessage safeMessageCopy(MuleMessage message)
127     {
128         return newMessage(message, SAFE);
129     }
130 
131     protected static MuleEvent newEvent(MuleEvent event, boolean safe)
132     {
133         if (safe && event instanceof ThreadSafeAccess)
134         {
135             return (MuleEvent) ((ThreadSafeAccess)event).newThreadCopy();
136         }
137         else
138         {
139             return event;
140         }
141     }
142 
143     protected static MuleMessage newMessage(MuleMessage message, boolean safe)
144     {
145         if (safe && message instanceof ThreadSafeAccess)
146         {
147             return (MuleMessage) ((ThreadSafeAccess)message).newThreadCopy();
148         }
149         else
150         {
151             return message;
152         }
153     }
154 
155     protected static void resetAccessControl(Object object)
156     {
157         if (object instanceof ThreadSafeAccess)
158         {
159             ((ThreadSafeAccess) object).resetAccessControl();
160         }
161     }
162 
163 }