1
2
3
4
5
6
7
8
9
10 package org.mule.config.spring;
11
12 import org.mule.config.spring.util.SpringXMLUtils;
13 import org.mule.util.StringUtils;
14
15 import javax.xml.parsers.DocumentBuilderFactory;
16 import javax.xml.parsers.ParserConfigurationException;
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20 import org.springframework.beans.factory.config.BeanDefinition;
21 import org.springframework.beans.factory.config.BeanDefinitionHolder;
22 import org.springframework.beans.factory.parsing.BeanComponentDefinition;
23 import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
24 import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
25 import org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader;
26 import org.springframework.beans.factory.xml.NamespaceHandler;
27 import org.springframework.beans.factory.xml.ParserContext;
28 import org.springframework.beans.factory.xml.XmlReaderContext;
29 import org.w3c.dom.Document;
30 import org.w3c.dom.Element;
31 import org.w3c.dom.NodeList;
32
33
34
35
36
37
38
39
40
41
42 public class MuleHierarchicalBeanDefinitionParserDelegate extends BeanDefinitionParserDelegate
43 {
44
45 public static final String BEANS = "beans";
46 public static final String MULE_REPEAT_PARSE = "org.mule.config.spring.MuleHierarchicalBeanDefinitionParserDelegate.MULE_REPEAT_PARSE";
47 public static final String MULE_NO_RECURSE = "org.mule.config.spring.MuleHierarchicalBeanDefinitionParserDelegate.MULE_NO_RECURSE";
48 public static final String MULE_FORCE_RECURSE = "org.mule.config.spring.MuleHierarchicalBeanDefinitionParserDelegate.MULE_FORCE_RECURSE";
49 public static final String MULE_NO_REGISTRATION = "org.mule.config.spring.MuleHierarchicalBeanDefinitionParserDelegate.MULE_NO_REGISTRATION";
50 public static final String MULE_POST_CHILDREN = "org.mule.config.spring.MuleHierarchicalBeanDefinitionParserDelegate.MULE_POST_CHILDREN";
51 private DefaultBeanDefinitionDocumentReader spring;
52
53 protected static final Log logger = LogFactory.getLog(MuleHierarchicalBeanDefinitionParserDelegate.class);
54
55 public MuleHierarchicalBeanDefinitionParserDelegate(XmlReaderContext readerContext,
56 DefaultBeanDefinitionDocumentReader spring)
57 {
58 super(readerContext);
59 this.spring = spring;
60 }
61
62 public BeanDefinition parseCustomElement(Element element, BeanDefinition parent)
63 {
64 if (logger.isDebugEnabled())
65 {
66 logger.debug("parsing: " + SpringXMLUtils.elementToString(element));
67 }
68 if (SpringXMLUtils.isBeansNamespace(element))
69 {
70 return handleSpringElements(element, parent);
71 }
72 else
73 {
74 String namespaceUri = element.getNamespaceURI();
75 NamespaceHandler handler = getReaderContext().getNamespaceHandlerResolver().resolve(namespaceUri);
76 if (handler == null)
77 {
78 getReaderContext().error("Unable to locate NamespaceHandler for namespace [" + namespaceUri + "]", element);
79 return null;
80 }
81
82 boolean noRecurse = false;
83 boolean forceRecurse = false;
84 BeanDefinition finalChild;
85
86 do {
87 ParserContext parserContext = new ParserContext(getReaderContext(), this, parent);
88 finalChild = handler.parse(element, parserContext);
89 registerBean(element, finalChild);
90 noRecurse = noRecurse || testFlag(finalChild, MULE_NO_RECURSE);
91 forceRecurse = forceRecurse || testFlag(finalChild, MULE_FORCE_RECURSE);
92 } while (null != finalChild && testFlag(finalChild, MULE_REPEAT_PARSE));
93
94
95
96
97
98
99
100
101
102
103
104 boolean isRecurse;
105 if (noRecurse)
106 {
107
108 isRecurse = false;
109 }
110 else
111 {
112 if (forceRecurse)
113 {
114 isRecurse = true;
115 }
116 else
117 {
118
119 isRecurse = SpringXMLUtils.isMuleNamespace(element);
120 }
121 }
122
123 if (isRecurse)
124 {
125 NodeList list = element.getChildNodes();
126 for (int i = 0; i < list.getLength(); i++)
127 {
128 if (list.item(i) instanceof Element)
129 {
130 parseCustomElement((Element) list.item(i), finalChild);
131 }
132 }
133 }
134
135
136
137 if (testFlag(finalChild, MULE_POST_CHILDREN))
138 {
139 ParserContext parserContext = new ParserContext(getReaderContext(), this, parent);
140 finalChild = handler.parse(element, parserContext);
141 }
142
143 return finalChild;
144 }
145 }
146
147 protected BeanDefinition handleSpringElements(Element element, BeanDefinition parent)
148 {
149
150
151
152
153 if (SpringXMLUtils.isLocalName(element, BEANS))
154 {
155
156
157
158 try
159 {
160 Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
161 doc.appendChild(doc.importNode(element, true));
162 spring.registerBeanDefinitions(doc, getReaderContext());
163 }
164 catch (ParserConfigurationException e)
165 {
166 throw new RuntimeException(e);
167 }
168 return parent;
169 }
170
171 else if (SpringXMLUtils.isLocalName(element, PROPERTY_ELEMENT))
172 {
173 parsePropertyElement(element, parent);
174 return parent;
175 }
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196 else if (SpringXMLUtils.isLocalName(element, BEAN_ELEMENT))
197 {
198 BeanDefinitionHolder holder = parseBeanDefinitionElement(element, parent);
199 registerBeanDefinitionHolder(holder);
200 return holder.getBeanDefinition();
201 }
202 else
203 {
204 throw new IllegalStateException("Unexpected Spring element: " + SpringXMLUtils.elementToString(element));
205 }
206 }
207
208 protected void registerBean(Element ele, BeanDefinition bd)
209 {
210 if (bd == null)
211 {
212 return;
213 }
214
215
216
217
218 if (! testFlag(bd, MULE_NO_REGISTRATION))
219 {
220 String name = generateChildBeanName(ele);
221 logger.debug("register " + name + ": " + bd.getBeanClassName());
222 registerBeanDefinitionHolder(new BeanDefinitionHolder(bd, name));
223 }
224 }
225
226 protected void registerBeanDefinitionHolder(BeanDefinitionHolder bdHolder)
227 {
228
229
230 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
231
232 getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
233 }
234
235 protected String generateChildBeanName(Element e)
236 {
237 String id = SpringXMLUtils.getNameOrId(e);
238 if (StringUtils.isBlank(id))
239 {
240 String parentId = SpringXMLUtils.getNameOrId((Element) e.getParentNode());
241 return "." + parentId + ":" + e.getLocalName();
242 }
243 else
244 {
245 return id;
246 }
247 }
248
249 public static void setFlag(BeanDefinition bean, String flag)
250 {
251 bean.setAttribute(flag, Boolean.TRUE);
252 }
253
254 public static boolean testFlag(BeanDefinition bean, String flag)
255 {
256 return null != bean
257 && bean.hasAttribute(flag)
258 && bean.getAttribute(flag) instanceof Boolean
259 && ((Boolean) bean.getAttribute(flag)).booleanValue();
260 }
261
262 }