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