View Javadoc

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