Coverage Report - org.mule.config.spring.parsers.generic.NameTransferDefinitionParser
 
Classes in this File Line Coverage Branch Coverage Complexity
NameTransferDefinitionParser
0%
0/17
0%
0/2
1.833
NameTransferDefinitionParser$1
N/A
N/A
1.833
NameTransferDefinitionParser$LocalBeanAssembler
0%
0/13
0%
0/12
1.833
NameTransferDefinitionParser$LocalBeanAssemblerFactory
0%
0/2
N/A
1.833
 
 1  
 /*
 2  
  * $Id:NameTransferDefinitionParser.java 7863 2007-08-13 20:20:43Z acooke $
 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  
 
 11  
 package org.mule.config.spring.parsers.generic;
 12  
 
 13  
 import org.mule.config.spring.parsers.assembly.BeanAssembler;
 14  
 import org.mule.config.spring.parsers.assembly.BeanAssemblerFactory;
 15  
 import org.mule.config.spring.parsers.assembly.DefaultBeanAssembler;
 16  
 import org.mule.config.spring.parsers.assembly.configuration.PropertyConfiguration;
 17  
 import org.mule.config.spring.parsers.assembly.configuration.SingleProperty;
 18  
 
 19  
 import org.springframework.beans.MutablePropertyValues;
 20  
 import org.springframework.beans.factory.config.BeanDefinition;
 21  
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
 22  
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
 23  
 import org.springframework.beans.factory.xml.ParserContext;
 24  
 import org.w3c.dom.Element;
 25  
 
 26  
 /**
 27  
  * This extends {@link ParentDefinitionParser} so that the "name" attribute is set locally,
 28  
  * not on the parent.
 29  
  *
 30  
  * <p>It's easier to understand with an example. Consider a custom security provider, set with the
 31  
  * following XML:</p>
 32  
  * <pre>
 33  
  &lt;mule:security-manager&gt;
 34  
      &lt;mule:custom-security-provider name="dummySecurityProvider"
 35  
                                     provider-ref="dummySecurityProvider"/&gt;
 36  
  &lt;/mule:security-manager&gt;</pre>
 37  
  * <p>What is happening here?  First, the custom-security-provider is being handled by this class.
 38  
  * Since this class extends ParentDefinitionParser, the provider value is set on the parent (the
 39  
  * security manager).  But we want the name attribute to be set on the provider (the referenced
 40  
  * bean).  So the "name" is set on the provider, not on the manager.  Then the provider is set on
 41  
  * the manager.</p> 
 42  
  */
 43  0
 public class NameTransferDefinitionParser extends ParentDefinitionParser
 44  
 {
 45  
 
 46  
     private String name;
 47  
     private String componentAttributeValue;
 48  
     private String componentAttributeName;
 49  
 
 50  
     /**
 51  
      * @param componentAttributeName The attribute name (after processing, which will strip "-ref",
 52  
      * add plurals, etc) that identifies the service which will receive the "name".
 53  
      */
 54  
     public NameTransferDefinitionParser(String componentAttributeName)
 55  0
     {
 56  0
         this.componentAttributeName = componentAttributeName;
 57  0
         setBeanAssemblerFactory(new LocalBeanAssemblerFactory());
 58  0
     }
 59  
 
 60  
     // this is a bit of a hack - we transfer the name to the provider
 61  
 
 62  
     // reset for each use
 63  
     protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext)
 64  
     {
 65  0
         name = null;
 66  0
         componentAttributeValue = null;
 67  0
         AbstractBeanDefinition bd = super.parseInternal(element, parserContext);
 68  0
         element.removeAttribute(ATTRIBUTE_NAME);
 69  0
         return bd; 
 70  
     }
 71  
 
 72  
 
 73  
     //  only set name if not already given
 74  
     private void setName()
 75  
     {
 76  0
         BeanDefinition beanDef = getParserContext().getRegistry().getBeanDefinition(componentAttributeValue);
 77  0
         MutablePropertyValues propertyValues = beanDef.getPropertyValues();
 78  0
         if (!propertyValues.contains(ATTRIBUTE_NAME))
 79  
         {
 80  0
             logger.debug("Setting " + ATTRIBUTE_NAME + " on " + componentAttributeValue + " to " + name);
 81  0
             propertyValues.addPropertyValue(ATTRIBUTE_NAME, name);
 82  
         }
 83  
         else
 84  
         {
 85  0
             logger.debug("Not setting " + ATTRIBUTE_NAME + " on " + componentAttributeValue +
 86  
                     " as already " + propertyValues.getPropertyValue(ATTRIBUTE_NAME));
 87  
         }
 88  0
     }
 89  
 
 90  
     private class LocalBeanAssembler extends DefaultBeanAssembler
 91  
     {
 92  
 
 93  
         public LocalBeanAssembler(PropertyConfiguration beanConfig, BeanDefinitionBuilder bean,
 94  
                                       PropertyConfiguration targetConfig, BeanDefinition target)
 95  0
         {
 96  0
             super(beanConfig, bean, targetConfig, target);
 97  0
         }
 98  
 
 99  
         protected void addPropertyWithReference(MutablePropertyValues properties, SingleProperty config, String name, Object value)
 100  
         {
 101  
             // intercept setting of name
 102  0
             if (ATTRIBUTE_NAME.equals(name) && value instanceof String)
 103  
             {
 104  0
                 NameTransferDefinitionParser.this.name = (String) value;
 105  
                 // name is set after service
 106  0
                 if (null != componentAttributeValue)
 107  
                 {
 108  0
                     setName();
 109  
                 }
 110  
             }
 111  
             else
 112  
             {
 113  0
                 super.addPropertyWithReference(properties, config, name, value);
 114  
 
 115  
                 // intercept setting of service
 116  0
                 if (componentAttributeName.equals(name) && value instanceof String)
 117  
                 {
 118  0
                     componentAttributeValue = (String) value;
 119  
                     // name was set before service
 120  0
                     if (null != NameTransferDefinitionParser.this.name)
 121  
                     {
 122  0
                         setName();
 123  
                     }
 124  
                 }
 125  
             }
 126  0
         }
 127  
     }
 128  
 
 129  0
     private class LocalBeanAssemblerFactory implements BeanAssemblerFactory
 130  
     {
 131  
 
 132  
         public BeanAssembler newBeanAssembler(PropertyConfiguration beanConfig, BeanDefinitionBuilder bean,
 133  
                                                       PropertyConfiguration targetConfig, BeanDefinition target)
 134  
         {
 135  0
             return new LocalBeanAssembler(beanConfig, bean, targetConfig, target);
 136  
         }
 137  
 
 138  
     }
 139  
 
 140  
 }