Coverage Report - org.mule.impl.RequestContext
 
Classes in this File Line Coverage Branch Coverage Complexity
RequestContext
71%
50/70
45%
19/42
2.353
 
 1  
 /*
 2  
  * $Id: RequestContext.java 7963 2007-08-21 08:53:15Z dirk.olmes $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.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.impl;
 12  
 
 13  
 import org.mule.config.MuleProperties;
 14  
 import org.mule.umo.UMOEvent;
 15  
 import org.mule.umo.UMOEventContext;
 16  
 import org.mule.umo.UMOExceptionPayload;
 17  
 import org.mule.umo.UMOMessage;
 18  
 
 19  
 import java.util.Iterator;
 20  
 
 21  
 import org.apache.commons.logging.Log;
 22  
 import org.apache.commons.logging.LogFactory;
 23  
 
 24  
 /**
 25  
  * <code>RequestContext</code> is a thread context where components can get the
 26  
  * current event or set response properties that will be sent on the outgoing
 27  
  * message.
 28  
  *
 29  
  * <p>RequestContext seems to be used to allow thread local mutation of events that
 30  
  * are not otherwise available in the scope.  so this is a good place to create a new
 31  
  * thread local copy - it will be read because supporting code is expecting mutation.</p>
 32  
  *
 33  
  */
 34  
 public final class RequestContext
 35  
 {
 36  
     // setting this to false gives old semantics in non-critical cases
 37  2
     private static boolean SAFE = true;
 38  4
     private static final Log logger = LogFactory.getLog(RequestContext.class);
 39  2
     private static final ThreadLocal currentEvent = new ThreadLocal();
 40  
 
 41  
     /** Do not instanciate. */
 42  
     protected RequestContext()
 43  0
     {
 44  
         // no-op
 45  0
     }
 46  
 
 47  
     public static UMOEventContext getEventContext()
 48  
     {
 49  74
         UMOEvent event = getEvent();
 50  74
         if (event != null)
 51  
         {
 52  74
             return new MuleEventContext(event);
 53  
         }
 54  
         else
 55  
         {
 56  0
             return null;
 57  
         }
 58  
     }
 59  
 
 60  
     public static UMOEvent getEvent()
 61  
     {
 62  128
         return (UMOEvent) currentEvent.get();
 63  
     }
 64  
 
 65  
     /**
 66  
      * Set an event for out-of-scope thread access.  Safe: use by default
 67  
      *
 68  
      * @param event - the event to set
 69  
      * @return A new mutable copy of the event set
 70  
      */
 71  
     public static UMOEvent setEvent(UMOEvent event)
 72  
     {
 73  444
         return internalSetEvent(newEvent(event, SAFE, false));
 74  
     }
 75  
 
 76  
     protected static UMOEvent internalSetEvent(UMOEvent event)
 77  
     {
 78  492
         currentEvent.set(event);
 79  492
         return event;
 80  
     }
 81  
 
 82  
     /**
 83  
      * Sets a new message payload in the RequestContext but maintains all other
 84  
      * properties (session, endpoint, synchronous, etc.) from the previous event.
 85  
      * Safe: use by default
 86  
      *
 87  
      * @param message - the new message payload
 88  
      * @return A new copy of the message set
 89  
      */
 90  
     public static UMOMessage rewriteEvent(UMOMessage message)
 91  
     {
 92  0
         return internalRewriteEvent(message, SAFE, false);
 93  
     }
 94  
 
 95  
     protected static UMOMessage internalRewriteEvent(UMOMessage message, boolean safe, boolean required)
 96  
     {
 97  6
         if (message != null)
 98  
         {
 99  6
             UMOEvent event = getEvent();
 100  6
             if (event != null)
 101  
             {
 102  6
                 UMOMessage copy = newMessage(message, safe, required);
 103  6
                 UMOEvent newEvent = new MuleEvent(copy, event);
 104  6
                 if (safe)
 105  
                 {
 106  0
                     resetAccessControl(copy);
 107  
                 }
 108  6
                 internalSetEvent(newEvent);
 109  6
                 return copy;
 110  
             }
 111  
         }
 112  0
         return message;
 113  
     }
 114  
 
 115  
     public static UMOMessage writeResponse(UMOMessage message)
 116  
     {
 117  0
         return internalWriteResponse(message, SAFE, false);
 118  
     }
 119  
 
 120  
     protected static UMOMessage internalWriteResponse(UMOMessage message, boolean safe, boolean required)
 121  
     {
 122  18
         if (message != null)
 123  
         {
 124  18
             UMOEvent event = getEvent();
 125  18
             if (event != null)
 126  
             {
 127  18
                 UMOMessage copy = newMessage(message, safe, required);
 128  18
                 combineProperties(event, copy);
 129  18
                 MuleEvent newEvent = new MuleEvent(copy, event.getEndpoint(), event.getSession(), event.isSynchronous());
 130  18
                 if (safe)
 131  
                 {
 132  0
                     resetAccessControl(copy);
 133  
                 }
 134  18
                 internalSetEvent(newEvent);
 135  18
                 return copy;
 136  
             }
 137  
         }
 138  0
         return message;
 139  
     }
 140  
 
 141  
     protected static void combineProperties(UMOEvent event, UMOMessage message)
 142  
     {
 143  18
         for (Iterator iterator = event.getMessage().getPropertyNames().iterator(); iterator.hasNext();)
 144  
         {
 145  84
             String key = (String) iterator.next();
 146  84
             if (key == null)
 147  
             {
 148  0
                 logger.warn("Message property key is null: please report the following stack trace to dev@mule.codehaus.org.",
 149  
                         new IllegalArgumentException());
 150  
             }
 151  
             else
 152  
             {
 153  84
                 if (key.startsWith(MuleProperties.PROPERTY_PREFIX))
 154  
                 {
 155  84
                     Object newValue = message.getProperty(key);
 156  84
                     Object oldValue = event.getMessage().getProperty(key);
 157  84
                     if (newValue == null)
 158  
                     {
 159  0
                         message.setProperty(key, oldValue);
 160  
                     }
 161  84
                     else if (logger.isInfoEnabled() && !newValue.equals(oldValue))
 162  
                     {
 163  0
                         logger.info("Message already contains property " + key + "=" + newValue
 164  
                                 + " not replacing old value: " + oldValue);
 165  
                     }
 166  
                 }
 167  
             }
 168  84
         }
 169  18
     }
 170  
 
 171  
     /**
 172  
      * Resets the current request context (clears all information).
 173  
      */
 174  
     public static void clear()
 175  
     {
 176  12
         setEvent(null);
 177  12
     }
 178  
 
 179  
     public static void setExceptionPayload(UMOExceptionPayload exceptionPayload)
 180  
     {
 181  4
         getEvent().getMessage().setExceptionPayload(exceptionPayload);
 182  4
     }
 183  
 
 184  
     public static UMOExceptionPayload getExceptionPayload()
 185  
     {
 186  0
         return getEvent().getMessage().getExceptionPayload();
 187  
     }
 188  
 
 189  
 
 190  
     // utility methods for thread safe access
 191  
 
 192  
     protected static void noteUse(String type)
 193  
     {
 194  204
         if (logger.isDebugEnabled())
 195  
         {
 196  0
             logger.debug("copying " + type, new Exception());
 197  
         }
 198  204
     }
 199  
 
 200  
     protected static UMOEvent newEvent(UMOEvent event, boolean safe, boolean required)
 201  
     {
 202  444
         if (safe && event instanceof ThreadSafeAccess)
 203  
         {
 204  204
             if (! required)
 205  
             {
 206  204
                 noteUse("event");
 207  
             }
 208  204
             return (UMOEvent) ((ThreadSafeAccess)event).newThreadCopy();
 209  
         }
 210  
         else
 211  
         {
 212  240
             return event;
 213  
         }
 214  
     }
 215  
 
 216  
     protected static UMOMessage newMessage(UMOMessage message, boolean safe, boolean required)
 217  
     {
 218  24
         if (safe && message instanceof ThreadSafeAccess)
 219  
         {
 220  0
             if (! required)
 221  
             {
 222  0
                 noteUse("message");
 223  
             }
 224  0
             return (UMOMessage) ((ThreadSafeAccess)message).newThreadCopy();
 225  
         }
 226  
         else
 227  
         {
 228  24
             return message;
 229  
         }
 230  
     }
 231  
 
 232  
     protected static void resetAccessControl(Object object)
 233  
     {
 234  0
         if (object instanceof ThreadSafeAccess)
 235  
         {
 236  0
             ((ThreadSafeAccess) object).resetAccessControl();
 237  
         }
 238  0
     }
 239  
 
 240  
 }