View Javadoc

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