Coverage Report - org.mule.config.bootstrap.SimpleRegistryBootstrap
 
Classes in this File Line Coverage Branch Coverage Complexity
SimpleRegistryBootstrap
72%
55/76
54%
15/28
3.667
 
 1  
 /*
 2  
  * $Id: SimpleRegistryBootstrap.java 12370 2008-07-17 13:11:17Z tcarlson $
 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.config.bootstrap;
 11  
 
 12  
 import org.mule.api.MuleContext;
 13  
 import org.mule.api.MuleException;
 14  
 import org.mule.api.context.MuleContextAware;
 15  
 import org.mule.api.lifecycle.Initialisable;
 16  
 import org.mule.api.lifecycle.InitialisationException;
 17  
 import org.mule.api.registry.ObjectProcessor;
 18  
 import org.mule.api.registry.Registry;
 19  
 import org.mule.api.transformer.DiscoverableTransformer;
 20  
 import org.mule.api.transformer.Transformer;
 21  
 import org.mule.api.transformer.TransformerException;
 22  
 import org.mule.api.util.StreamCloser;
 23  
 import org.mule.config.i18n.CoreMessages;
 24  
 import org.mule.util.ClassUtils;
 25  
 import org.mule.util.PropertiesUtils;
 26  
 
 27  
 import java.lang.reflect.InvocationTargetException;
 28  
 import java.net.URL;
 29  
 import java.util.Enumeration;
 30  
 import java.util.Iterator;
 31  
 import java.util.Map;
 32  
 import java.util.Properties;
 33  
 
 34  
 /**
 35  
  * This object will load objects defined in a file called <code>registry-bootstrap.properties</code> into the local registry.
 36  
  * This allows modules and transports to make certain objects available by default.  The most common use case is for a
 37  
  * module or transport to load stateless transformers into the registry.
 38  
  * For this file to be located it must be present in the modules META-INF directory under
 39  
  * <code>META-INF/services/org/mule/config/</code>
 40  
  * <p/>
 41  
  * The format of this file is a simple key / value pair. i.e.
 42  
  * <code>
 43  
  * myobject=org.foo.MyObject
 44  
  * </code>
 45  
  * <p/>
 46  
  * Will register an instance of MyObject with a key of 'myobject'. If you don't care about the object name and want to
 47  
  * ensure that the ojbect gets a unique name you can use -
 48  
  * <code>
 49  
  * object.1=org.foo.MyObject
 50  
  * object.2=org.bar.MyObject
 51  
  * </code>
 52  
  * <p/>
 53  
  * or
 54  
  * <code>
 55  
  * myFoo=org.foo.MyObject
 56  
  * myBar=org.bar.MyObject
 57  
  * </code>
 58  
  * <p/>
 59  
  * <p/>
 60  
  * Loading transformers has a slightly different notation since you can define the 'returnClass' and 'name'of
 61  
  * the transformer as parameters i.e.
 62  
  * <p/>
 63  
  * <code>
 64  
  * transformer.1=org.mule.transport.jms.transformers.JMSMessageToObject,returnClass=byte[]
 65  
  * transformer.2=org.mule.transport.jms.transformers.JMSMessageToObject,returnClass=java.lang.String, name=JMSMessageToString
 66  
  * transformer.3=org.mule.transport.jms.transformers.JMSMessageToObject,returnClass=java.util.Hashtable)
 67  
  * </code>
 68  
  * <p/>
 69  
  * Note that the key used for transformers must be 'transformer.x' where 'x' is a sequential number.  The transformer name will be
 70  
  * automatically generated as JMSMessageToXXX where XXX is the return class name i.e. JMSMessageToString unless a 'name'
 71  
  * parameter is specified. If no 'returnClass' is specified the defualt in the transformer will be used.
 72  
  * <p/>
 73  
  * Note that all objects defined have to have a default constructor. They can implement injection interfaces such as
 74  
  * {@link org.mule.api.context.MuleContextAware} and lifecylce interfaces such as {@link org.mule.api.lifecycle.Initialisable}.
 75  
  */
 76  1146
 public class SimpleRegistryBootstrap implements Initialisable, MuleContextAware
 77  
 {
 78  
     public static final String SERVICE_PATH = "META-INF/services/org/mule/config/";
 79  
 
 80  
     public static final String REGISTRY_PROPERTIES = "registry-bootstrap.properties";
 81  
 
 82  1146
     public String TRANSFORMER_PREFIX = "transformer.";
 83  1146
     public String OBJECT_PREFIX = "object.";
 84  
 
 85  
 
 86  
     protected MuleContext context;
 87  
 
 88  
     /** {@inheritDoc} */
 89  
     public void setMuleContext(MuleContext context)
 90  
     {
 91  1146
         this.context = context;
 92  1146
     }
 93  
 
 94  
     /** {@inheritDoc} */
 95  
     public void initialise() throws InitialisationException
 96  
     {
 97  1146
         Enumeration e = ClassUtils.getResources(SERVICE_PATH + REGISTRY_PROPERTIES, getClass());
 98  2292
         while (e.hasMoreElements())
 99  
         {
 100  
             try
 101  
             {
 102  1146
                 URL url = (URL) e.nextElement();
 103  1146
                 Properties p = new Properties();
 104  1146
                 p.load(url.openStream());
 105  1146
                 process(p);
 106  
             }
 107  0
             catch (Exception e1)
 108  
             {
 109  0
                 throw new InitialisationException(e1, this);
 110  1146
             }
 111  
         }
 112  1146
     }
 113  
 
 114  
     protected void process(Properties props) throws NoSuchMethodException, IllegalAccessException, MuleException, InvocationTargetException, ClassNotFoundException, InstantiationException
 115  
     {
 116  1146
         registerTransformers(props, context.getRegistry());
 117  1146
         registerUnnamedObjects(props, context.getRegistry());
 118  
         //this must be called last as it clears the properties map
 119  1146
         registerObjects(props, context.getRegistry());
 120  
 
 121  1146
     }
 122  
 
 123  
     private void registerTransformers(Properties props, Registry registry) throws MuleException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException, ClassNotFoundException
 124  
     {
 125  1146
         int i = 1;
 126  1146
         String transString = props.getProperty(TRANSFORMER_PREFIX + i);
 127  1146
         String name = null;
 128  1146
         String returnClassString = null;
 129  
 
 130  5730
         while (transString != null)
 131  
         {
 132  4584
             Class returnClass = null;
 133  4584
             int x = transString.indexOf(",");
 134  4584
             if (x > -1)
 135  
             {
 136  0
                 Properties p = PropertiesUtils.getPropertiesFromString(transString.substring(i + 1), ',');
 137  0
                 name = p.getProperty("name", null);
 138  0
                 returnClassString = p.getProperty("returnClass", null);
 139  
             }
 140  
 
 141  4584
             if (returnClassString != null)
 142  
             {
 143  0
                 if (returnClassString.equals("byte[]"))
 144  
                 {
 145  0
                     returnClass = byte[].class;
 146  
                 }
 147  
                 else
 148  
                 {
 149  0
                     returnClass = ClassUtils.loadClass(returnClassString, getClass());
 150  
                 }
 151  
             }
 152  4584
             String transClass = (x == -1 ? transString : transString.substring(0, x));
 153  4584
             Transformer trans = (Transformer) ClassUtils.instanciateClass(transClass, ClassUtils.NO_ARGS);
 154  4584
             if (!(trans instanceof DiscoverableTransformer))
 155  
             {
 156  0
                 throw new TransformerException(CoreMessages.transformerNotImplementDiscoverable(trans));
 157  
             }
 158  4584
             if (returnClass != null)
 159  
             {
 160  0
                 trans.setReturnClass(returnClass);
 161  
             }
 162  4584
             if (name != null)
 163  
             {
 164  0
                 trans.setName(name);
 165  
             }
 166  
             else
 167  
             {
 168  
                 //This will generate a default name for the transformer
 169  4584
                 name = trans.getName();
 170  
                 //We then prefix the name to ensure there is less chance of conflict if the user registers
 171  
                 // the transformer with the same name
 172  4584
                 trans.setName("_" + name);
 173  
             }
 174  4584
             registry.registerTransformer(trans);
 175  4584
             props.remove(TRANSFORMER_PREFIX + i++);
 176  4584
             name = null;
 177  4584
             returnClass = null;
 178  4584
             transString = props.getProperty(TRANSFORMER_PREFIX + i);
 179  4584
         }
 180  1146
     }
 181  
 
 182  
     private void registerObjects(Properties props, Registry registry) throws MuleException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException, ClassNotFoundException
 183  
     {
 184  
         //Note that caling the other register methods first will have removed any processed entries
 185  1146
         for (Iterator iterator = props.entrySet().iterator(); iterator.hasNext();)
 186  
         {
 187  0
             Map.Entry entry = (Map.Entry) iterator.next();
 188  0
             Object object = ClassUtils.instanciateClass(entry.getValue().toString(), ClassUtils.NO_ARGS);
 189  0
             String key = entry.getKey().toString();
 190  0
             Class meta = Object.class;
 191  0
             if(object instanceof ObjectProcessor)
 192  
             {
 193  0
                 meta = ObjectProcessor.class;
 194  
             }
 195  0
             registry.registerObject(key, object, meta);
 196  0
         }
 197  1146
         props.clear();
 198  1146
     }
 199  
 
 200  
     private void registerUnnamedObjects(Properties props, Registry registry) throws MuleException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException, ClassNotFoundException
 201  
     {
 202  1146
         int i = 1;
 203  1146
         String objectString = props.getProperty(OBJECT_PREFIX + i);
 204  14898
         while (objectString != null)
 205  
         {
 206  
 
 207  13752
             Object o = ClassUtils.instanciateClass(objectString, ClassUtils.NO_ARGS);
 208  13752
             Class meta = Object.class;
 209  13752
             if(o instanceof ObjectProcessor)
 210  
             {
 211  0
                 meta = ObjectProcessor.class;
 212  
             }
 213  13752
             else if(o instanceof StreamCloser)
 214  
             {
 215  0
                 meta = StreamCloser.class;
 216  
             }
 217  13752
             registry.registerObject(OBJECT_PREFIX + i + "#" + o.hashCode(), o, meta);
 218  13752
             props.remove(OBJECT_PREFIX + i++);
 219  13752
             objectString = props.getProperty(OBJECT_PREFIX + i);
 220  13752
         }
 221  1146
     }
 222  
 }