Coverage Report - org.mule.MessagePropertiesContext
 
Classes in this File Line Coverage Branch Coverage Complexity
MessagePropertiesContext
0%
0/110
0%
0/52
0
 
 1  
 /*
 2  
  * $Id: MessagePropertiesContext.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  
 package org.mule;
 11  
 
 12  
 import org.mule.api.MuleEvent;
 13  
 import org.mule.api.MuleSession;
 14  
 import org.mule.api.transport.PropertyScope;
 15  
 import org.mule.util.CaseInsensitiveHashMap;
 16  
 import org.mule.util.MapUtils;
 17  
 import org.mule.util.ObjectUtils;
 18  
 
 19  
 import java.io.Serializable;
 20  
 import java.util.Collections;
 21  
 import java.util.HashMap;
 22  
 import java.util.HashSet;
 23  
 import java.util.Map;
 24  
 import java.util.Set;
 25  
 import java.util.TreeMap;
 26  
 import java.util.TreeSet;
 27  
 
 28  
 import org.apache.commons.logging.Log;
 29  
 import org.apache.commons.logging.LogFactory;
 30  
 
 31  
 /**
 32  
  * This object maintains a scoped map of properties.  This means that certain properties will only be visible under some
 33  
  * scopes. The scopes supported by Mule are:
 34  
  * <ol>
 35  
  * <li> {@link org.mule.api.transport.PropertyScope#INBOUND} Contains properties that were on the message when it was
 36  
  * received by Mule.  This scope is read-only.</li>
 37  
  * <li>{@link org.mule.api.transport.PropertyScope#INVOCATION} Any properties set on the invocation scope will be
 38  
  * available to the current service but will not be attached to any outbound messages.</li>
 39  
  * <li>{@link org.mule.api.transport.PropertyScope#OUTBOUND} Any properties set in this scope will be attached to any
 40  
  * outbound messages resulting from this message.  This is the default scope.</li>
 41  
  * <li>{@link org.mule.api.transport.PropertyScope#SESSION} Any properties set on this scope will be added to the session.
 42  
  * Note that this is a convenience scope in that you cannot directly access session properties from this scope.  Session
 43  
  * properties can be accessed from the {@link MuleEvent}</li>
 44  
  * </ol>
 45  
  */
 46  
 public class MessagePropertiesContext implements Serializable
 47  
 {
 48  
     private static final long serialVersionUID = -5230693402768953742L;
 49  0
     private static final PropertyScope DEFAULT_SCOPE = PropertyScope.OUTBOUND;
 50  
 
 51  0
     private Log logger = LogFactory.getLog(getClass());
 52  
 
 53  
     /**
 54  
      * Map of maps containing the scoped properties, each scope has its own Map.
 55  
      */
 56  
     protected Map<PropertyScope, Map<String, Object>> scopedMap;
 57  
 
 58  
     /**
 59  
      * The union of all property names from all scopes.
 60  
      */
 61  
     protected Set<String> keySet;
 62  
 
 63  
 
 64  
     @SuppressWarnings("unchecked")
 65  
     public MessagePropertiesContext()
 66  0
     {
 67  0
         keySet = new TreeSet<String>();
 68  0
         scopedMap = new TreeMap<PropertyScope, Map<String, Object>>(new PropertyScope.ScopeComparator());
 69  
 
 70  0
         scopedMap.put(PropertyScope.INVOCATION, new CaseInsensitiveHashMap/*<String, Object>*/(6));
 71  0
         scopedMap.put(PropertyScope.INBOUND, new CaseInsensitiveHashMap/*<String, Object>*/(6));
 72  0
         scopedMap.put(PropertyScope.OUTBOUND, new CaseInsensitiveHashMap/*<String, Object>*/(6));
 73  0
     }
 74  
 
 75  
     protected Map<String, Object> getScopedProperties(PropertyScope scope)
 76  
     {
 77  0
         Map<String, Object> map = scopedMap.get(scope);
 78  0
         if (map == null)
 79  
         {
 80  0
             throw new IllegalArgumentException("Scope not registered: " + scope);
 81  
         }
 82  0
         return map;
 83  
     }
 84  
 
 85  
     public PropertyScope getDefaultScope()
 86  
     {
 87  0
         return DEFAULT_SCOPE;
 88  
     }
 89  
 
 90  
     protected void addInboundProperties(Map<String, Object> properties)
 91  
     {
 92  0
         if (properties != null)
 93  
         {
 94  0
             Map<String, Object> props = new HashMap<String, Object>(properties.size());
 95  0
             for (String key : properties.keySet())
 96  
             {
 97  0
                 props.put(key, properties.get(key));
 98  
             }
 99  0
             getScopedProperties(PropertyScope.INBOUND).putAll(props);
 100  0
             keySet.addAll(props.keySet());
 101  
         }
 102  0
     }
 103  
 
 104  
     /**
 105  
      *
 106  
      * @deprecated use the overloaded version with an explicit lookup scope. This method will
 107  
      * now use only the outbound scope.
 108  
      */
 109  
     @Deprecated
 110  
     public Object getProperty(String key)
 111  
     {
 112  0
         return getProperty(key, PropertyScope.OUTBOUND);
 113  
     }
 114  
 
 115  
     @SuppressWarnings("unchecked")
 116  
     public <T> T getProperty(String key, PropertyScope scope)
 117  
     {
 118  0
         if (scope == null)
 119  
         {
 120  0
             return (T) getProperty(key, PropertyScope.OUTBOUND);
 121  
         }
 122  
 
 123  0
         T value = null;
 124  0
         if (PropertyScope.SESSION.equals(scope))
 125  
         {
 126  0
             if (RequestContext.getEvent() != null)
 127  
             {
 128  0
                 value = (T) RequestContext.getEvent().getSession().getProperty(key);
 129  
             }
 130  
         }
 131  
         else
 132  
         {
 133  0
             value = (T) scopedMap.get(scope).get(key);
 134  
         }
 135  0
         return value;
 136  
     }
 137  
 
 138  
     /**
 139  
      * Removes all properties from all scopes except for SESSION and INBOUND (which is read-only).
 140  
      * You may explicitly clear the session properties by calling clearProperties(PropertyScope.SESSION)
 141  
      */
 142  
     public void clearProperties()
 143  
     {
 144  0
         Map<String, Object> props = getScopedProperties(PropertyScope.INVOCATION);
 145  0
         keySet.removeAll(props.keySet());
 146  0
         props.clear();
 147  0
         props = getScopedProperties(PropertyScope.OUTBOUND);
 148  0
         keySet.removeAll(props.keySet());
 149  0
         props.clear();
 150  0
     }
 151  
 
 152  
     public void clearProperties(PropertyScope scope)
 153  
     {
 154  0
         if (scope == null)
 155  
         {
 156  0
             clearProperties();
 157  0
             return;
 158  
         }
 159  
 
 160  
         //checkScopeForWriteAccess(scope);
 161  0
         if (PropertyScope.SESSION.equals(scope))
 162  
         {
 163  0
             if (RequestContext.getEvent() != null)
 164  
             {
 165  0
                 MuleSession session = RequestContext.getEvent().getSession();
 166  0
                 for (Object key : session.getPropertyNamesAsSet())
 167  
                 {
 168  0
                     session.removeProperty(key);
 169  
                 }
 170  0
             }
 171  
         }
 172  
         else
 173  
         {
 174  0
             Map<String, Object> props = getScopedProperties(scope);
 175  0
             keySet.removeAll(props.keySet());
 176  0
             props.clear();
 177  
         }
 178  0
     }
 179  
 
 180  
     /**
 181  
      * Removes a property from all scopes except for SESSION and INBOUND (which is read-only).
 182  
      * You may explicitly remove a session property by calling removeProperty(key, PropertyScope.SESSION)
 183  
      *
 184  
      * @param key the property key to remove
 185  
      * @return the removed property value or null if the property did not exist
 186  
      */
 187  
     public Object removeProperty(String key)
 188  
     {
 189  0
         Object value = getScopedProperties(PropertyScope.OUTBOUND).remove(key);
 190  0
         Object inv = getScopedProperties(PropertyScope.INVOCATION).remove(key);
 191  
 
 192  0
         keySet.remove(key);
 193  
 
 194  0
         if (value == null)
 195  
         {
 196  0
             value = inv;
 197  
         }
 198  
 
 199  0
         return value;
 200  
     }
 201  
 
 202  
     /**
 203  
      * Removes a property from the specified property scope.
 204  
      *
 205  
      * @param key the property key to remove
 206  
      * @return the removed property value or null if the property did not exist
 207  
      */
 208  
     public Object removeProperty(String key, PropertyScope scope)
 209  
     {
 210  0
         if (scope == null)
 211  
         {
 212  0
             return removeProperty(key);
 213  
         }
 214  
 
 215  0
         Object value = null;
 216  0
         if (PropertyScope.SESSION.equals(scope))
 217  
         {
 218  0
             if (RequestContext.getEvent() != null)
 219  
             {
 220  0
                 value = RequestContext.getEvent().getSession().removeProperty(key);
 221  
             }
 222  
         }
 223  
         else
 224  
         {
 225  0
             value = getScopedProperties(scope).remove(key);
 226  
         }
 227  
 
 228  
         // Only remove the property from the keySet if it does not exist in any other scope besides this one.
 229  0
         if (getProperty(key, PropertyScope.OUTBOUND) == null
 230  
                 && getProperty(key, PropertyScope.INVOCATION) == null
 231  
                 && getProperty(key, PropertyScope.INBOUND) == null)
 232  
         {
 233  0
             keySet.remove(key);
 234  
         }
 235  
 
 236  0
         return value;
 237  
     }
 238  
 
 239  
     /**
 240  
      * Set a property on the message
 241  
      *
 242  
      * @param key   the key on which to associate the value
 243  
      * @param value the property value
 244  
      * @deprecated use {@link #setProperty(String, Object, org.mule.api.transport.PropertyScope)}
 245  
      */
 246  
     @Deprecated
 247  
     public void setProperty(String key, Object value)
 248  
     {
 249  0
         getScopedProperties(DEFAULT_SCOPE).put(key, value);
 250  0
         keySet.add(key);
 251  0
     }
 252  
 
 253  
     /**
 254  
      * Set a property on the message
 255  
      *
 256  
      * @param key   the key on which to associate the value
 257  
      * @param value the property value
 258  
      * @param scope the scope to se the property on
 259  
      * @see org.mule.api.transport.PropertyScope
 260  
      */
 261  
     public void setProperty(String key, Object value, PropertyScope scope)
 262  
     {
 263  
         //checkScopeForWriteAccess(scope);
 264  0
         if (PropertyScope.SESSION.equals(scope))
 265  
         {
 266  0
             if (RequestContext.getEvent() != null)
 267  
             {
 268  0
                 RequestContext.getEvent().getSession().setProperty(key, value);
 269  
             }
 270  
             else
 271  
             {
 272  0
                 logger.warn(String.format("Detected an attempt to set a session property, " +
 273  
                                           "but MuleEvent isn't available in this thread. Key/value: %s=%s %s",
 274  
                                           key, value, Thread.currentThread()));
 275  
             }
 276  
         }
 277  
         else
 278  
         {
 279  0
             getScopedProperties(scope).put(key, value);
 280  0
             keySet.add(key);
 281  
         }
 282  0
     }
 283  
 
 284  
     /**
 285  
      * @deprecated use {@link #getPropertyNames(org.mule.api.transport.PropertyScope)}
 286  
      */
 287  
     @Deprecated
 288  
     public Set<String> getPropertyNames()
 289  
     {
 290  0
         Set<String> allProps = new HashSet<String>();
 291  0
         allProps.addAll(keySet);
 292  0
         if (RequestContext.getEvent() != null)
 293  
         {
 294  0
             allProps.addAll(RequestContext.getEvent().getSession().getPropertyNamesAsSet());
 295  
         }
 296  0
         return allProps;
 297  
     }
 298  
 
 299  
     /**
 300  
      * @return all property keys on this message for the given scope
 301  
      */
 302  
     public Set<String> getPropertyNames(PropertyScope scope)
 303  
     {
 304  0
         if (PropertyScope.SESSION.equals(scope))
 305  
         {
 306  0
             if (RequestContext.getEvent() != null)
 307  
             {
 308  0
                 return RequestContext.getEvent().getSession().getPropertyNamesAsSet();
 309  
             }
 310  
             else
 311  
             {
 312  0
                 return Collections.emptySet();
 313  
             }
 314  
         }
 315  
         else
 316  
         {
 317  0
             return Collections.unmodifiableSet(getScopedProperties(scope).keySet());
 318  
         }
 319  
     }
 320  
 
 321  
     protected void checkScopeForWriteAccess(PropertyScope scope)
 322  
     {
 323  0
         if (scope == null || PropertyScope.INBOUND.equals(scope))
 324  
         {
 325  0
             throw new IllegalArgumentException("Scope is invalid for writing properties: " + scope);
 326  
         }
 327  0
     }
 328  
 
 329  
     public Object getProperty(String key, Object defaultValue)
 330  
     {
 331  0
         Object value = getProperty(key);
 332  0
         if (value == null)
 333  
         {
 334  0
             value = defaultValue;
 335  
         }
 336  0
         return value;
 337  
     }
 338  
 
 339  
     public byte getByteProperty(String name, byte defaultValue)
 340  
     {
 341  0
         return ObjectUtils.getByte(getProperty(name), defaultValue);
 342  
     }
 343  
 
 344  
     public short getShortProperty(String name, short defaultValue)
 345  
     {
 346  0
         return ObjectUtils.getShort(getProperty(name), defaultValue);
 347  
     }
 348  
 
 349  
     public int getIntProperty(String name, int defaultValue)
 350  
     {
 351  0
         return ObjectUtils.getInt(getProperty(name), defaultValue);
 352  
     }
 353  
 
 354  
     public long getLongProperty(String name, long defaultValue)
 355  
     {
 356  0
         return ObjectUtils.getLong(getProperty(name), defaultValue);
 357  
     }
 358  
 
 359  
     public float getFloatProperty(String name, float defaultValue)
 360  
     {
 361  0
         return ObjectUtils.getFloat(getProperty(name), defaultValue);
 362  
     }
 363  
 
 364  
     public double getDoubleProperty(String name, double defaultValue)
 365  
     {
 366  0
         return ObjectUtils.getDouble(getProperty(name), defaultValue);
 367  
     }
 368  
 
 369  
     public boolean getBooleanProperty(String name, boolean defaultValue)
 370  
     {
 371  0
         return ObjectUtils.getBoolean(getProperty(name), defaultValue);
 372  
     }
 373  
 
 374  
     @Deprecated
 375  
     public String getStringProperty(String name, String defaultValue)
 376  
     {
 377  0
         return getStringProperty(name, PropertyScope.OUTBOUND, defaultValue);
 378  
     }
 379  
 
 380  
     public String getStringProperty(String name, PropertyScope scope, String defaultValue)
 381  
     {
 382  0
         return ObjectUtils.getString(getProperty(name, scope), defaultValue);
 383  
     }
 384  
 
 385  
     @Override
 386  
     public String toString()
 387  
     {
 388  0
         StringBuffer buf = new StringBuffer(128);
 389  0
         buf.append("Properties{");
 390  0
         for (Map.Entry<PropertyScope, Map<String, Object>> entry : scopedMap.entrySet())
 391  
         {
 392  0
             buf.append(entry.getKey()).append(":");
 393  0
             buf.append(MapUtils.toString(entry.getValue(), false));
 394  0
             buf.append(", ");
 395  
         }
 396  0
         buf.append("}");
 397  0
         return buf.toString();
 398  
     }
 399  
 }