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