Coverage Report - org.mule.registry.TransientRegistry
 
Classes in this File Line Coverage Branch Coverage Complexity
TransientRegistry
71%
120/170
61%
34/56
2.212
 
 1  
 /*
 2  
  * $Id: TransientRegistry.java 12269 2008-07-10 04:19:03Z dfeist $
 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  
 package org.mule.registry;
 11  
 
 12  
 import org.mule.MuleServer;
 13  
 import org.mule.RegistryContext;
 14  
 import org.mule.api.MuleContext;
 15  
 import org.mule.api.MuleException;
 16  
 import org.mule.api.agent.Agent;
 17  
 import org.mule.api.endpoint.EndpointBuilder;
 18  
 import org.mule.api.endpoint.ImmutableEndpoint;
 19  
 import org.mule.api.lifecycle.InitialisationException;
 20  
 import org.mule.api.lifecycle.LifecycleManager;
 21  
 import org.mule.api.lifecycle.LifecyclePhase;
 22  
 import org.mule.api.lifecycle.Stoppable;
 23  
 import org.mule.api.model.Model;
 24  
 import org.mule.api.registry.AbstractServiceDescriptor;
 25  
 import org.mule.api.registry.ObjectProcessor;
 26  
 import org.mule.api.registry.RegistrationException;
 27  
 import org.mule.api.registry.Registry;
 28  
 import org.mule.api.registry.ServiceDescriptor;
 29  
 import org.mule.api.registry.ServiceDescriptorFactory;
 30  
 import org.mule.api.registry.ServiceException;
 31  
 import org.mule.api.service.Service;
 32  
 import org.mule.api.transformer.DiscoverableTransformer;
 33  
 import org.mule.api.transformer.Transformer;
 34  
 import org.mule.api.transport.Connector;
 35  
 import org.mule.config.i18n.CoreMessages;
 36  
 import org.mule.lifecycle.GenericLifecycleManager;
 37  
 import org.mule.lifecycle.phases.TransientRegistryDisposePhase;
 38  
 import org.mule.lifecycle.phases.TransientRegistryInitialisePhase;
 39  
 import org.mule.util.BeanUtils;
 40  
 import org.mule.util.ClassUtils;
 41  
 import org.mule.util.SpiUtils;
 42  
 
 43  
 import java.util.Collection;
 44  
 import java.util.HashMap;
 45  
 import java.util.Iterator;
 46  
 import java.util.Map;
 47  
 import java.util.Properties;
 48  
 
 49  
 import org.apache.commons.logging.Log;
 50  
 import org.apache.commons.logging.LogFactory;
 51  
 
 52  
 public class TransientRegistry extends AbstractRegistry
 53  
 {
 54  
     /** logger used by this class */
 55  1160
     protected transient final Log logger = LogFactory.getLog(TransientRegistry.class);
 56  
     public static final String REGISTRY_ID = "org.mule.Registry.Transient";
 57  
 
 58  
     /** Map of Maps registry */
 59  
     private Map registry;
 60  
 
 61  
     public TransientRegistry()
 62  
     {
 63  1160
         super(REGISTRY_ID);
 64  1160
         init();
 65  1160
     }
 66  
 
 67  
     public TransientRegistry(Registry parent)
 68  
     {
 69  0
         super(REGISTRY_ID, parent);
 70  0
         init();
 71  0
     }
 72  
 
 73  
     private void init()
 74  
     {
 75  1160
         registry = new HashMap(8);
 76  
 
 77  1160
         getObjectTypeMap(ObjectProcessor.class).put("_muleExpressionEvaluatorProcessor",
 78  
                 new ExpressionEvaluatorProcessor());
 79  
 
 80  1160
         RegistryContext.setRegistry(this);
 81  
         try
 82  
         {
 83  1160
             initialise();
 84  
         }
 85  0
         catch (InitialisationException e)
 86  
         {
 87  0
             logger.error(e);
 88  1160
         }
 89  
 
 90  1160
     }
 91  
 
 92  
     protected LifecycleManager createLifecycleManager()
 93  
     {
 94  1160
         GenericLifecycleManager lcm = new GenericLifecycleManager();
 95  1160
         LifecyclePhase initPhase = new TransientRegistryInitialisePhase();
 96  1160
         initPhase.setRegistryScope(Registry.SCOPE_IMMEDIATE);
 97  1160
         lcm.registerLifecycle(initPhase);
 98  1160
         LifecyclePhase disposePhase = new TransientRegistryDisposePhase();
 99  1160
         disposePhase.setRegistryScope(Registry.SCOPE_IMMEDIATE);
 100  1160
         lcm.registerLifecycle(disposePhase);
 101  1160
         return lcm;
 102  
     }
 103  
 
 104  
     //@java.lang.Override
 105  
     protected void doInitialise() throws InitialisationException
 106  
     {
 107  1160
         int oldScope = getDefaultScope();
 108  1160
         setDefaultScope(Registry.SCOPE_IMMEDIATE);
 109  
         try
 110  
         {
 111  1160
             applyProcessors(getConnectors());
 112  1160
             applyProcessors(getTransformers());
 113  1160
             applyProcessors(getEndpoints());
 114  1160
             applyProcessors(getAgents());
 115  1160
             applyProcessors(getModels());
 116  1160
             applyProcessors(lookupServices());
 117  1160
             applyProcessors(lookupObjects(Object.class));
 118  
         }
 119  
         finally
 120  
         {
 121  1160
             setDefaultScope(oldScope);
 122  1160
         }
 123  
 
 124  1160
     }
 125  
 
 126  
     protected void applyProcessors(Map objects)
 127  
     {
 128  0
         if (objects == null)
 129  
         {
 130  0
             return;
 131  
         }
 132  0
         for (Iterator iterator = objects.values().iterator(); iterator.hasNext();)
 133  
         {
 134  0
             Object o = iterator.next();
 135  0
             Collection processors = lookupObjects(ObjectProcessor.class);
 136  0
             for (Iterator iterator2 = processors.iterator(); iterator2.hasNext();)
 137  
             {
 138  0
                 ObjectProcessor op = (ObjectProcessor) iterator2.next();
 139  0
                 op.process(o);
 140  0
             }
 141  0
         }
 142  0
     }
 143  
 
 144  
 
 145  
     public void registerObjects(Map objects) throws RegistrationException
 146  
     {
 147  4
         if (objects == null)
 148  
         {
 149  0
             return;
 150  
         }
 151  
 
 152  4
         for (Iterator iterator = objects.entrySet().iterator(); iterator.hasNext();)
 153  
         {
 154  8
             Map.Entry entry = (Map.Entry) iterator.next();
 155  8
             registerObject(entry.getKey().toString(), entry.getValue());
 156  8
         }
 157  4
     }
 158  
 
 159  
     protected Object doLookupObject(String key)
 160  
     {
 161  10024
         Object o = null;
 162  10024
         if (key != null)
 163  
         {
 164  
             Map map;
 165  10024
             for (Iterator it = registry.values().iterator(); it.hasNext();)
 166  
             {
 167  30183
                 map = (Map) it.next();
 168  30183
                 o = map.get(key);
 169  30183
                 if (o != null)
 170  
                 {
 171  4350
                     return o;
 172  
                 }
 173  
             }
 174  
         }
 175  5674
         return o;
 176  
     }
 177  
 
 178  
     public Collection doLookupObjects(Class returntype)
 179  
     {
 180  65002
         Map map = (Map) registry.get(returntype);
 181  65002
         if (map != null)
 182  
         {
 183  42840
             return map.values();
 184  
         }
 185  
         else
 186  
         {
 187  22162
             return null;
 188  
         }
 189  
     }
 190  
 
 191  
     /** Looks up the service descriptor from a singleton cache and creates a new one if not found. */
 192  
     public ServiceDescriptor lookupServiceDescriptor(String type, String name, Properties overrides) throws ServiceException
 193  
     {
 194  1542
         String key = new AbstractServiceDescriptor.Key(name, overrides).getKey();
 195  
         //TODO If we want these descriptors loaded form Spring we need to checnge the key mechanism
 196  
         //and the scope, and then deal with circular reference issues.
 197  1542
         ServiceDescriptor sd = (ServiceDescriptor) lookupObject(key);
 198  
 
 199  1542
         synchronized (this)
 200  
         {
 201  1542
             if (sd == null)
 202  
             {
 203  390
                 sd = createServiceDescriptor(type, name, overrides);
 204  
                 try
 205  
                 {
 206  390
                     registerObject(key, sd, ServiceDescriptor.class);
 207  
                 }
 208  0
                 catch (RegistrationException e)
 209  
                 {
 210  0
                     throw new ServiceException(e.getI18nMessage(), e);
 211  390
                 }
 212  
             }
 213  1542
         }
 214  1542
         return sd;
 215  
     }
 216  
 
 217  
     // TODO ServiceDescriptors will be created upon bundle startup for OSGi. 
 218  
     protected ServiceDescriptor createServiceDescriptor(String type, String name, Properties overrides) throws ServiceException
 219  
     {
 220  390
         Properties props = SpiUtils.findServiceDescriptor(type, name);
 221  390
         if (props == null)
 222  
         {
 223  0
             throw new ServiceException(CoreMessages.failedToLoad(type + " " + name));
 224  
         }
 225  390
         return ServiceDescriptorFactory.create(type, name, props, overrides, this);
 226  
     }
 227  
 
 228  
     protected Map getObjectTypeMap(Object o)
 229  
     {
 230  34598
         if (o == null)
 231  
         {
 232  13112
             o = Object.class;
 233  
         }
 234  
 
 235  
         Object key;
 236  34598
         if (o instanceof Class)
 237  
         {
 238  34596
             key = o;
 239  
         }
 240  2
         else if (o instanceof String)
 241  
         {
 242  0
             key = o;
 243  
         }
 244  
         else
 245  
         {
 246  2
             key = o.getClass();
 247  
         }
 248  34598
         Map objects = (Map) registry.get(key);
 249  34598
         if (objects == null)
 250  
         {
 251  5414
             objects = new HashMap(8);
 252  5414
             registry.put(key, objects);
 253  
         }
 254  34598
         return objects;
 255  
     }
 256  
 
 257  
     protected Object applyProcessors(Object object)
 258  
     {
 259  41556
         Object theObject = object;
 260  
         // this may be an incorrect hack.  the problem is that if we try to lookup objects in spring before
 261  
         // it is initialised, we end up triggering object creation.  that causes circular dependencies because
 262  
         // this may have originally been called while creating objects in spring...  so we prevent that by
 263  
         // only doing the full lookup once everything is stable.  ac.
 264  41556
         Collection processors = 
 265  
                 lookupObjects(ObjectProcessor.class,
 266  
                         (null != getParent() && getParent().isInitialised()) ? getDefaultScope() : SCOPE_IMMEDIATE);
 267  41556
         for (Iterator iterator = processors.iterator(); iterator.hasNext();)
 268  
         {
 269  41556
             ObjectProcessor o = (ObjectProcessor) iterator.next();
 270  41556
             theObject = o.process(theObject);
 271  41556
         }
 272  41556
         return theObject;
 273  
     }
 274  
 
 275  
     /**
 276  
      * Allows for arbitary registration of transient objects
 277  
      *
 278  
      * @param key
 279  
      * @param value
 280  
      */
 281  
     protected void doRegisterObject(String key, Object value) throws RegistrationException
 282  
     {
 283  0
         doRegisterObject(key, value, Object.class);
 284  0
     }
 285  
 
 286  
     /**
 287  
      * Allows for arbitary registration of transient objects
 288  
      *
 289  
      * @param key
 290  
      * @param value
 291  
      */
 292  
     protected void doRegisterObject(String key, Object object, Object metadata) throws RegistrationException
 293  
     {
 294  33436
         logger.debug("registering object");
 295  33436
         if (isInitialised() || isInitialising())
 296  
         {
 297  33436
             logger.debug("applying processors");
 298  33436
             object = applyProcessors(object);
 299  
         }
 300  
 
 301  33436
         Map objectMap = getObjectTypeMap(metadata);
 302  33436
         if (objectMap != null)
 303  
         {
 304  33436
             if (objectMap.containsKey(key))
 305  
             {
 306  
                 // objectMap.put(key, value) would overwrite a previous entity with the same name.  Is this really what we want?
 307  
                 // Not sure whether to throw an exception or log a warning here.
 308  
                 //throw new RegistrationException("TransientRegistry already contains an object named '" + key + "'.  The previous object would be overwritten.");
 309  20
                 logger.warn("TransientRegistry already contains an object named '" + key + "'.  The previous object will be overwritten.");
 310  
             }
 311  33436
             objectMap.put(key, object);
 312  
             try
 313  
             {
 314  33436
                 MuleContext mc = MuleServer.getMuleContext();
 315  33436
                 logger.debug("context: " + mc);
 316  33436
                 if (mc != null)
 317  
                 {
 318  33436
                     logger.debug("applying lifecycle");
 319  33436
                     mc.applyLifecycle(object);
 320  
                 }
 321  
                 else
 322  
                 {
 323  0
                     throw new RegistrationException("Unable to register object (\""
 324  
                             + key + ":" + ClassUtils.getSimpleName(object.getClass())
 325  
                             + "\") because MuleContext has not yet been created.");
 326  
                 }
 327  
             }
 328  0
             catch (MuleException e)
 329  
             {
 330  0
                 throw new RegistrationException(e);
 331  33436
             }
 332  
         }
 333  
         else
 334  
         {
 335  0
             throw new RegistrationException("No object map exists for type " + metadata);
 336  
         }
 337  33436
     }
 338  
 
 339  
     //@java.lang.Override
 340  
     public void registerAgent(Agent agent) throws MuleException
 341  
     {
 342  0
         registerObject(agent.getName(), agent, Agent.class);
 343  0
     }
 344  
 
 345  
     //@java.lang.Override
 346  
     public void registerConnector(Connector connector) throws MuleException
 347  
     {
 348  42
         registerObject(connector.getName(), connector, Connector.class);
 349  42
     }
 350  
 
 351  
     //@java.lang.Override
 352  
     public void registerEndpoint(ImmutableEndpoint endpoint) throws MuleException
 353  
     {
 354  0
         registerObject(endpoint.getName(), endpoint, ImmutableEndpoint.class);
 355  0
     }
 356  
 
 357  
     public void registerEndpointBuilder(String name, EndpointBuilder builder) throws MuleException
 358  
     {
 359  8
         registerObject(name, builder, EndpointBuilder.class);
 360  8
     }
 361  
 
 362  
     //@java.lang.Override
 363  
     public void registerModel(Model model) throws MuleException
 364  
     {
 365  1150
         registerObject(model.getName(), model, Model.class);
 366  1150
     }
 367  
 
 368  
     //@java.lang.Override
 369  
     protected void doRegisterTransformer(Transformer transformer) throws MuleException
 370  
     {
 371  
         //TODO should we always throw an exception if an object already exists
 372  4592
         if (lookupTransformer(transformer.getName()) != null)
 373  
         {
 374  0
             throw new RegistrationException(CoreMessages.objectAlreadyRegistered("transformer: " +
 375  
                     transformer.getName(), lookupTransformer(transformer.getName()), transformer).getMessage());
 376  
         }
 377  4592
         registerObject(transformer.getName(), transformer, Transformer.class);
 378  4592
     }
 379  
 
 380  
     //@java.lang.Override
 381  
     public void registerService(Service service) throws MuleException
 382  
     {
 383  388
         registerObject(service.getName(), service, Service.class);
 384  388
     }
 385  
 
 386  
     protected void unregisterObject(String key, Object metadata) throws MuleException
 387  
     {
 388  2
         Object obj = getObjectTypeMap(metadata).remove(key);
 389  2
         if (obj instanceof Stoppable)
 390  
         {
 391  0
             ((Stoppable) obj).stop();
 392  
         }
 393  2
     }
 394  
 
 395  
     public void unregisterObject(String key) throws MuleException
 396  
     {
 397  0
         unregisterObject(key, Object.class);
 398  0
     }
 399  
 
 400  
     //@java.lang.Override
 401  
     public void unregisterService(String serviceName) throws MuleException
 402  
     {
 403  0
         unregisterObject(serviceName, Service.class);
 404  0
     }
 405  
 
 406  
 
 407  
     //@java.lang.Override
 408  
     public void unregisterAgent(String agentName) throws MuleException
 409  
     {
 410  0
         unregisterObject(agentName, Agent.class);
 411  0
     }
 412  
 
 413  
     //@java.lang.Override
 414  
     public void unregisterConnector(String connectorName) throws MuleException
 415  
     {
 416  0
         unregisterObject(connectorName, Connector.class);
 417  0
     }
 418  
 
 419  
     //@java.lang.Override
 420  
     public void unregisterEndpoint(String endpointName) throws MuleException
 421  
     {
 422  0
         unregisterObject(endpointName, ImmutableEndpoint.class);
 423  0
     }
 424  
 
 425  
     //@java.lang.Override
 426  
     public void unregisterModel(String modelName) throws MuleException
 427  
     {
 428  0
         unregisterObject(modelName, Model.class);
 429  0
     }
 430  
 
 431  
     //@java.lang.Override
 432  
     public void unregisterTransformer(String transformerName) throws MuleException
 433  
     {
 434  2
         Transformer transformer = lookupTransformer(transformerName);
 435  2
         if (transformer instanceof DiscoverableTransformer)
 436  
         {
 437  2
             exactTransformerCache.clear();
 438  2
             transformerListCache.clear();
 439  
         }
 440  2
         unregisterObject(transformerName, Transformer.class);
 441  2
     }
 442  
 
 443  
     //@java.lang.Override
 444  
     public Transformer lookupTransformer(String name)
 445  
     {
 446  4594
         Transformer transformer = super.lookupTransformer(name);
 447  4594
         if (transformer != null)
 448  
         {
 449  
             try
 450  
             {
 451  2
                 if (transformer.getEndpoint() != null)
 452  
                 {
 453  0
                     throw new IllegalStateException("Endpoint cannot be set");
 454  
                 }
 455  
 //                Map props = BeanUtils.describe(transformer);
 456  
 //                props.remove("endpoint");
 457  
 //                props.remove("strategy");
 458  
 //                transformer = (Transformer)ClassUtils.instanciateClass(transformer.getClass(), ClassUtils.NO_ARGS);
 459  
                 //TODO: friggin' cloning
 460  2
                 transformer = (Transformer) BeanUtils.cloneBean(transformer);
 461  
             }
 462  0
             catch (Exception e)
 463  
             {
 464  
                 //TODO MULE-3532
 465  0
                 e.printStackTrace();
 466  2
             }
 467  
         }
 468  4594
         return transformer;
 469  
     }
 470  
 
 471  
     public boolean isReadOnly()
 472  
     {
 473  0
         return false;
 474  
     }
 475  
 
 476  
     public boolean isRemote()
 477  
     {
 478  0
         return false;
 479  
     }
 480  
 
 481  
 }