View Javadoc

1   /*
2    * $Id: AbstractChildElementIterator.java 19456 2010-09-08 17:07:59Z esteban.robles $
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  
11  package org.mule.config.spring.parsers.processors;
12  
13  import org.mule.config.spring.parsers.PostProcessor;
14  import org.mule.config.spring.parsers.assembly.BeanAssembler;
15  import org.mule.config.spring.parsers.assembly.BeanAssemblerFactory;
16  import org.mule.config.spring.parsers.assembly.configuration.PropertyConfiguration;
17  import org.mule.config.spring.util.SpringXMLUtils;
18  
19  import org.w3c.dom.Element;
20  import org.w3c.dom.NodeList;
21  import org.w3c.dom.Node;
22  import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
23  import org.springframework.beans.factory.xml.ParserContext;
24  import org.springframework.beans.factory.config.BeanDefinition;
25  
26  /**
27   * This iterates over child elements, parsing them and calling
28   * {@link #insertBean(org.mule.config.spring.parsers.assembly.BeanAssembler, org.springframework.beans.factory.config.BeanDefinition, org.w3c.dom.Element, org.w3c.dom.Element)}.
29   *
30   * <p>There are two ways we can parse a tree of elements - have an external loop or let each parser iterate
31   * over its own children.  Mule uses the first strategy, but some (most? all?) third party BDPs use the
32   * second.  This processor lets us use third party beans inside the Mule framework.
33   *
34   * <p>So this is a very specialised parser that should only be used when trying to inter-operate with beans from
35   * third party packages which themselves control how their children are parsed.
36   *
37   * <p>Since for Mule beans the iteration over child elements (at least currently) is done via
38   * {@link org.mule.config.spring.MuleHierarchicalBeanDefinitionParserDelegate} the calling parser needs to set
39   * the flag {@link org.mule.config.spring.MuleHierarchicalBeanDefinitionParserDelegate#MULE_NO_RECURSE} - this
40   * stops the Mule recursion from working.
41   *
42   * <p>NOTE - IMHO (ac) the Mule approach was probably a mistake; this processor could be used as a way to
43   * slowly migrate the Mule code to the more common approach.
44   */
45  public abstract class AbstractChildElementIterator implements PostProcessor
46  {
47  
48      private BeanAssemblerFactory beanAssemblerFactory;
49      private PropertyConfiguration configuration;
50  
51      public AbstractChildElementIterator(BeanAssemblerFactory beanAssemblerFactory, PropertyConfiguration configuration)
52      {
53          this.beanAssemblerFactory = beanAssemblerFactory;
54          this.configuration = configuration;
55      }
56  
57      public void postProcess(ParserContext context, BeanAssembler assembler, Element element)
58      {
59          NodeList children = element.getChildNodes();
60          for (int i = 0; i < children.getLength(); ++i)
61          {
62              Node child = children.item(i);
63              if (child.getNodeType() == Node.ELEMENT_NODE)
64              {
65                  processChildElement(context, assembler, element, (Element) child);
66              }
67          }
68      }
69  
70      protected void processChildElement(ParserContext context, BeanAssembler assembler, Element parent, Element child)
71      {
72          Object childBean = null;
73          if (SpringXMLUtils.isBeansNamespace(child)
74              || SpringXMLUtils.isLocalName(child, BeanDefinitionParserDelegate.REF_ELEMENT))
75          {
76              childBean = context.getDelegate().parsePropertySubElement(child, null);
77          }
78          else
79          {
80              childBean = context.getDelegate().parseCustomElement(child,
81                  assembler.getBean().getBeanDefinition());
82          }
83          BeanAssembler targetAssembler = beanAssemblerFactory.newBeanAssembler(null, null, configuration,
84              assembler.getBean().getRawBeanDefinition());
85          insertBean(targetAssembler, childBean, parent, child);
86      }
87  
88      protected abstract void insertBean(BeanAssembler targetAssembler, Object childBean, Element parent, Element child);
89  
90  }