Coverage Report - org.mule.registry.TransientRegistry
 
Classes in this File Line Coverage Branch Coverage Complexity
TransientRegistry
0%
0/114
0%
0/48
0
 
 1  
 /*
 2  
  * $Id: TransientRegistry.java 20267 2010-11-19 03:15:43Z dfeist $
 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.registry;
 11  
 
 12  
 import org.mule.api.MuleContext;
 13  
 import org.mule.api.MuleException;
 14  
 import org.mule.api.agent.Agent;
 15  
 import org.mule.api.endpoint.ImmutableEndpoint;
 16  
 import org.mule.api.lifecycle.Disposable;
 17  
 import org.mule.api.lifecycle.InitialisationException;
 18  
 import org.mule.api.model.Model;
 19  
 import org.mule.api.registry.InjectProcessor;
 20  
 import org.mule.api.registry.MuleRegistry;
 21  
 import org.mule.api.registry.ObjectProcessor;
 22  
 import org.mule.api.registry.PreInitProcessor;
 23  
 import org.mule.api.registry.RegistrationException;
 24  
 import org.mule.api.service.Service;
 25  
 import org.mule.api.transformer.Transformer;
 26  
 import org.mule.api.transport.Connector;
 27  
 import org.mule.config.i18n.MessageFactory;
 28  
 import org.mule.lifecycle.phases.NotInLifecyclePhase;
 29  
 import org.mule.util.CollectionUtils;
 30  
 import org.mule.util.StringUtils;
 31  
 
 32  
 import java.util.Collection;
 33  
 import java.util.HashMap;
 34  
 import java.util.Iterator;
 35  
 import java.util.Map;
 36  
 
 37  
 import org.apache.commons.collections.functors.InstanceofPredicate;
 38  
 import org.apache.commons.logging.Log;
 39  
 import org.apache.commons.logging.LogFactory;
 40  
 
 41  
 /**
 42  
  * Use synchronized(registry) when reading/writing/iterating over the contents of the registry hashmap.
 43  
  */
 44  
 //@ThreadSafe
 45  
 public class TransientRegistry extends AbstractRegistry
 46  
 {
 47  
     /** logger used by this class */
 48  0
     protected transient final Log logger = LogFactory.getLog(TransientRegistry.class);
 49  
     public static final String REGISTRY_ID = "org.mule.Registry.Transient";
 50  
 
 51  
     //@ThreadSafe synchronized(registry)
 52  0
     private final Map<String, Object> registry = new HashMap<String, Object>();
 53  
 
 54  
 
 55  
     public TransientRegistry(MuleContext muleContext)
 56  
     {
 57  0
         this(REGISTRY_ID, muleContext);
 58  0
     }
 59  
 
 60  
     public TransientRegistry(String id, MuleContext muleContext)
 61  
     {
 62  0
         super(id, muleContext);
 63  0
         synchronized(registry)
 64  
         {
 65  0
             registry.put("_muleContextProcessor", new MuleContextProcessor(muleContext));
 66  
             //registry.put("_muleNotificationProcessor", new NotificationListenersProcessor(muleContext));
 67  0
             registry.put("_muleExpressionEvaluatorProcessor", new ExpressionEvaluatorProcessor(muleContext));
 68  0
             registry.put("_muleExpressionEnricherProcessor", new ExpressionEnricherProcessor(muleContext));
 69  0
             registry.put("_muleLifecycleStateInjectorProcessor", new LifecycleStateInjectorProcessor(getLifecycleManager().getState()));
 70  0
             registry.put("_muleLifecycleManager", getLifecycleManager());
 71  0
         }
 72  0
     }
 73  
 
 74  
     @Override
 75  
     protected void doInitialise() throws InitialisationException
 76  
     {
 77  0
         applyProcessors(lookupObjects(Connector.class), null);
 78  0
         applyProcessors(lookupObjects(Transformer.class), null);
 79  0
         applyProcessors(lookupObjects(ImmutableEndpoint.class), null);
 80  0
         applyProcessors(lookupObjects(Agent.class), null);
 81  0
         applyProcessors(lookupObjects(Model.class), null);
 82  0
         applyProcessors(lookupObjects(Service.class), null);
 83  0
         applyProcessors(lookupObjects(Object.class), null);
 84  0
     }
 85  
 
 86  
     @Override
 87  
     protected void doDispose()
 88  
     {
 89  0
         registry.clear();
 90  0
     }
 91  
 
 92  
     protected Map applyProcessors(Map<String, Object> objects)
 93  
     {
 94  0
         if (objects == null)
 95  
         {
 96  0
             return null;
 97  
         }
 98  0
         Map<String, Object> results = new HashMap<String, Object>();
 99  0
         for (Map.Entry<String, Object> entry : objects.entrySet())
 100  
         {
 101  
             //We do this in the loop in case the map contains ObjectProcessors
 102  0
             Collection<ObjectProcessor> processors = lookupObjects(ObjectProcessor.class);
 103  0
             for (ObjectProcessor processor : processors)
 104  
             {
 105  0
                 Object result = processor.process(entry.getValue());
 106  
                 //If result is null do not add the object
 107  0
                 if(result != null)
 108  
                 {
 109  0
                     results.put(entry.getKey(), result);
 110  
                 }
 111  0
             }
 112  0
         }
 113  0
         return results;
 114  
     }
 115  
 
 116  
 
 117  
     public void registerObjects(Map objects) throws RegistrationException
 118  
     {
 119  0
         if (objects == null)
 120  
         {
 121  0
             return;
 122  
         }
 123  
 
 124  0
         for (Iterator iterator = objects.entrySet().iterator(); iterator.hasNext();)
 125  
         {
 126  0
             Map.Entry entry = (Map.Entry) iterator.next();
 127  0
             registerObject(entry.getKey().toString(), entry.getValue());
 128  0
         }
 129  0
     }
 130  
 
 131  
     @SuppressWarnings("unchecked")
 132  
     public <T> Map<String, T> lookupByType(Class<T> type)
 133  
     {
 134  0
         synchronized(registry)
 135  
         {
 136  0
             final Map<String, T> results = new HashMap<String, T>();
 137  0
             for (Map.Entry<String, Object> entry : registry.entrySet())
 138  
             {
 139  0
                 final Class clazz = entry.getValue().getClass();
 140  0
                 if (type.isAssignableFrom(clazz))
 141  
                 {
 142  0
                     results.put(entry.getKey(), (T) entry.getValue());
 143  
                 }
 144  0
             }
 145  
 
 146  0
             return results;
 147  0
         }
 148  
     }
 149  
 
 150  
     @SuppressWarnings("unchecked")
 151  
     public <T> T  lookupObject(String key)
 152  
     {
 153  0
         synchronized(registry)
 154  
         {
 155  0
             return (T) registry.get(key);
 156  0
         }
 157  
     }
 158  
 
 159  
     @SuppressWarnings("unchecked")
 160  
     public <T> Collection<T> lookupObjects(Class<T> returntype)
 161  
     {
 162  0
         synchronized(registry)
 163  
         {
 164  0
             return CollectionUtils.select(registry.values(), new InstanceofPredicate(returntype));
 165  0
         }
 166  
     }
 167  
 
 168  
     /**
 169  
      * Will fire any lifecycle methods according to the current lifecycle without actually
 170  
      * registering the object in the registry.  This is useful for prototype objects that are created per request and would
 171  
      * clutter the registry with single use objects.
 172  
      *
 173  
      * @param object the object to process
 174  
      * @return the same object with lifecycle methods called (if it has any)
 175  
      * @throws org.mule.api.MuleException if the registry fails to perform the lifecycle change for the object.
 176  
      */
 177  
     Object applyLifecycle(Object object) throws MuleException
 178  
     {
 179  0
         getLifecycleManager().applyCompletedPhases(object);
 180  0
         return object;
 181  
     }
 182  
 
 183  
     Object applyLifecycle(Object object, String phase) throws MuleException
 184  
     {
 185  0
         getLifecycleManager().applyPhase(object, NotInLifecyclePhase.PHASE_NAME, phase);
 186  0
         return object;
 187  
     }
 188  
 
 189  
 
 190  
 
 191  
     Object applyProcessors(Object object, Object metadata)
 192  
     {
 193  0
         Object theObject = object;
 194  
 
 195  0
         if(!hasFlag(metadata, MuleRegistry.INJECT_PROCESSORS_BYPASS_FLAG))
 196  
         {
 197  
             //Process injectors first
 198  0
             Collection<InjectProcessor> injectProcessors = lookupObjects(InjectProcessor.class);
 199  0
             for (InjectProcessor processor : injectProcessors)
 200  
             {
 201  0
                 theObject = processor.process(theObject);
 202  
             }
 203  
         }
 204  
 
 205  0
         if(!hasFlag(metadata, MuleRegistry.PRE_INIT_PROCESSORS_BYPASS_FLAG))
 206  
         {
 207  
             //Then any other processors
 208  0
             Collection<PreInitProcessor> processors = lookupObjects(PreInitProcessor.class);
 209  0
             for (PreInitProcessor processor : processors)
 210  
             {
 211  0
                 theObject = processor.process(theObject);
 212  0
                 if(theObject==null)
 213  
                 {
 214  0
                     return null;
 215  
                 }
 216  
             }
 217  
         }
 218  0
         return theObject;
 219  
     }
 220  
 
 221  
     /**
 222  
      * Allows for arbitary registration of transient objects
 223  
      *
 224  
      * @param key
 225  
      * @param value
 226  
      */
 227  
     public void registerObject(String key, Object value) throws RegistrationException
 228  
     {
 229  0
         registerObject(key, value, Object.class);
 230  0
     }
 231  
 
 232  
     /**
 233  
      * Allows for arbitrary registration of transient objects
 234  
      *
 235  
      * @param key
 236  
      */
 237  
     public void registerObject(String key, Object object, Object metadata) throws RegistrationException
 238  
     {
 239  0
         checkDisposed();
 240  0
         if (StringUtils.isBlank(key))
 241  
         {
 242  0
             throw new RegistrationException(MessageFactory.createStaticMessage("Attempt to register object with no key"));
 243  
         }
 244  
 
 245  0
         if (logger.isDebugEnabled())
 246  
         {
 247  0
             logger.debug(String.format("registering key/object %s/%s", key, object));
 248  
         }
 249  
         
 250  0
         logger.debug("applying processors");
 251  0
         object = applyProcessors(object, metadata);
 252  
         //Don't add the object if the processor returns null
 253  0
         if (object==null)
 254  
         {
 255  0
             return;
 256  
         }
 257  
 
 258  0
         synchronized(registry)
 259  
         {
 260  0
             if (registry.containsKey(key))
 261  
             {
 262  
                 // registry.put(key, value) would overwrite a previous entity with the same name.  Is this really what we want?
 263  
                 // Not sure whether to throw an exception or log a warning here.
 264  
                 //throw new RegistrationException("TransientRegistry already contains an object named '" + key + "'.  The previous object would be overwritten.");
 265  0
                 logger.warn("TransientRegistry already contains an object named '" + key + "'.  The previous object will be overwritten.");
 266  
             }
 267  0
             registry.put(key, object);
 268  0
         }
 269  
 
 270  
         try
 271  
         {
 272  0
             if (!hasFlag(metadata, MuleRegistry.LIFECYCLE_BYPASS_FLAG))
 273  
             {
 274  0
                 if(logger.isDebugEnabled())
 275  
                 {
 276  0
                     logger.debug("applying lifecycle to object: " + object);
 277  
                 }
 278  0
                 getLifecycleManager().applyCompletedPhases(object);
 279  
             }
 280  
         }
 281  0
         catch (MuleException e)
 282  
         {
 283  0
             throw new RegistrationException(e);
 284  0
         }
 285  0
     }
 286  
 
 287  
 
 288  
     protected void checkDisposed() throws RegistrationException
 289  
     {
 290  0
         if(getLifecycleManager().isPhaseComplete(Disposable.PHASE_NAME))
 291  
         {
 292  0
             throw new RegistrationException(MessageFactory.createStaticMessage("Cannot register objects on the registry as the context is disposed"));
 293  
         }
 294  0
     }
 295  
 
 296  
     protected boolean hasFlag(Object metaData, int flag)
 297  
     {
 298  0
         return !(metaData == null || !(metaData instanceof Integer)) && ((Integer) metaData & flag) != 0;
 299  
     }
 300  
 
 301  
     /**
 302  
      * Will remove an object by name from the registry. By default the registry will apply all remaining lifecycle phases
 303  
      * to the object when it is removed.
 304  
      *
 305  
      * @param key the name or key of the object to remove from the registry
 306  
      * @param metadata Meta data flags supported are {@link org.mule.api.registry.MuleRegistry#LIFECYCLE_BYPASS_FLAG}
 307  
      * @throws RegistrationException if there is a problem unregistering the object. Typically this will be because
 308  
      * the object's lifecycle threw an exception
 309  
      */
 310  
     public void unregisterObject(String key, Object metadata) throws RegistrationException
 311  
     {
 312  
         Object obj;
 313  0
         synchronized (registry)
 314  
         {
 315  0
             obj = registry.remove(key);
 316  0
         }
 317  
 
 318  
         try
 319  
         {
 320  0
             if(!hasFlag(metadata, MuleRegistry.LIFECYCLE_BYPASS_FLAG))
 321  
             {
 322  0
                 getLifecycleManager().applyPhase(obj, lifecycleManager.getCurrentPhase(), Disposable.PHASE_NAME);
 323  
             }
 324  
         }
 325  0
         catch (MuleException e)
 326  
         {
 327  0
             throw new RegistrationException(e);
 328  0
         }
 329  
 
 330  0
     }
 331  
 
 332  
     public void unregisterObject(String key) throws RegistrationException
 333  
     {
 334  0
         unregisterObject(key, Object.class);
 335  0
     }
 336  
 
 337  
     // /////////////////////////////////////////////////////////////////////////
 338  
     // Registry Metadata
 339  
     // /////////////////////////////////////////////////////////////////////////
 340  
 
 341  
     public boolean isReadOnly()
 342  
     {
 343  0
         return false;
 344  
     }
 345  
 
 346  
     public boolean isRemote()
 347  
     {
 348  0
         return false;
 349  
     }
 350  
 
 351  
 }