1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
package org.apache.camel.spring.handler; |
18 |
|
|
19 |
|
import java.util.HashSet; |
20 |
|
import java.util.Set; |
21 |
|
|
22 |
|
import javax.xml.bind.JAXBContext; |
23 |
|
import javax.xml.bind.JAXBException; |
24 |
|
import javax.xml.bind.Unmarshaller; |
25 |
|
|
26 |
|
import org.w3c.dom.Element; |
27 |
|
import org.w3c.dom.Node; |
28 |
|
import org.w3c.dom.NodeList; |
29 |
|
|
30 |
|
import org.apache.camel.builder.xml.XPathBuilder; |
31 |
|
import org.apache.camel.spring.CamelBeanPostProcessor; |
32 |
|
import org.apache.camel.spring.CamelContextFactoryBean; |
33 |
|
import org.apache.camel.spring.EndpointFactoryBean; |
34 |
|
import org.apache.camel.spring.remoting.CamelProxyFactoryBean; |
35 |
|
import org.apache.camel.spring.remoting.CamelServiceExporter; |
36 |
|
import org.apache.camel.util.ObjectHelper; |
37 |
|
|
38 |
|
import org.springframework.beans.factory.BeanDefinitionStoreException; |
39 |
|
import org.springframework.beans.factory.config.BeanDefinition; |
40 |
|
import org.springframework.beans.factory.config.RuntimeBeanReference; |
41 |
|
import org.springframework.beans.factory.parsing.BeanComponentDefinition; |
42 |
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder; |
43 |
|
import org.springframework.beans.factory.xml.NamespaceHandlerSupport; |
44 |
|
import org.springframework.beans.factory.xml.ParserContext; |
45 |
|
import org.springframework.util.xml.DomUtils; |
46 |
|
|
47 |
|
import static org.apache.camel.util.ObjectHelper.isNotNullAndNonEmpty; |
48 |
|
|
49 |
50 |
public class CamelNamespaceHandler extends NamespaceHandlerSupport { |
50 |
|
public static final String JAXB_PACKAGES = "org.apache.camel.spring:org.apache.camel.model:org.apache.camel.model.language"; |
51 |
|
|
52 |
50 |
protected BeanDefinitionParser endpointParser = new BeanDefinitionParser(EndpointFactoryBean.class); |
53 |
50 |
protected BeanDefinitionParser proxyParser = new BeanDefinitionParser(CamelProxyFactoryBean.class); |
54 |
50 |
protected BeanDefinitionParser exportParser = new BeanDefinitionParser(CamelServiceExporter.class); |
55 |
50 |
protected BeanDefinitionParser beanPostProcessorParser = new BeanDefinitionParser(CamelBeanPostProcessor.class); |
56 |
|
|
57 |
50 |
protected Set<String> parserElementNames = new HashSet<String>(); |
58 |
|
private JAXBContext jaxbContext; |
59 |
|
|
60 |
|
public void init() { |
61 |
50 |
registerParser("endpoint", endpointParser); |
62 |
50 |
registerParser("proxy", proxyParser); |
63 |
50 |
registerParser("export", exportParser); |
64 |
|
|
65 |
50 |
registerParser("camelContext", new BeanDefinitionParser(CamelContextFactoryBean.class) { |
66 |
|
@Override |
67 |
50 |
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { |
68 |
53 |
super.doParse(element, parserContext, builder); |
69 |
|
|
70 |
53 |
String contextId = element.getAttribute("id"); |
71 |
|
|
72 |
|
|
73 |
|
|
74 |
53 |
if (ObjectHelper.isNullOrBlank(contextId)) { |
75 |
7 |
contextId = "camelContext"; |
76 |
7 |
element.setAttribute("id", contextId); |
77 |
|
} |
78 |
|
|
79 |
|
|
80 |
53 |
Object value = parseUsingJaxb(element, parserContext); |
81 |
53 |
if (value instanceof CamelContextFactoryBean) { |
82 |
53 |
CamelContextFactoryBean factoryBean = (CamelContextFactoryBean)value; |
83 |
53 |
builder.addPropertyValue("routes", factoryBean.getRoutes()); |
84 |
|
|
85 |
53 |
if (factoryBean.getPackages().length > 0) { |
86 |
4 |
builder.addPropertyValue("packages", factoryBean.getPackages()); |
87 |
|
} |
88 |
|
} |
89 |
|
|
90 |
53 |
boolean createdBeanPostProcessor = false; |
91 |
53 |
NodeList list = element.getChildNodes(); |
92 |
53 |
int size = list.getLength(); |
93 |
232 |
for (int i = 0; i < size; i++) { |
94 |
179 |
Node child = list.item(i); |
95 |
179 |
if (child instanceof Element) { |
96 |
62 |
Element childElement = (Element)child; |
97 |
62 |
String localName = child.getLocalName(); |
98 |
62 |
if (localName.equals("beanPostProcessor")) { |
99 |
8 |
createBeanPostProcessor(parserContext, contextId, childElement); |
100 |
8 |
createdBeanPostProcessor = true; |
101 |
8 |
} else if (localName.equals("endpoint")) { |
102 |
11 |
BeanDefinition definition = endpointParser.parse(childElement, parserContext); |
103 |
11 |
String id = childElement.getAttribute("id"); |
104 |
11 |
if (isNotNullAndNonEmpty(id)) { |
105 |
|
|
106 |
11 |
definition.getPropertyValues().addPropertyValue("context", new RuntimeBeanReference(contextId)); |
107 |
|
|
108 |
|
|
109 |
11 |
parserContext.registerComponent(new BeanComponentDefinition(definition, id)); |
110 |
|
} |
111 |
11 |
} else if (localName.equals("proxy")) { |
112 |
0 |
BeanDefinition definition = proxyParser.parse(childElement, parserContext); |
113 |
0 |
String id = childElement.getAttribute("id"); |
114 |
0 |
if (isNotNullAndNonEmpty(id)) { |
115 |
0 |
parserContext.registerComponent(new BeanComponentDefinition(definition, id)); |
116 |
|
} |
117 |
0 |
} else if (localName.equals("export")) { |
118 |
0 |
BeanDefinition definition = exportParser.parse(childElement, parserContext); |
119 |
0 |
String id = childElement.getAttribute("id"); |
120 |
0 |
if (isNotNullAndNonEmpty(id)) { |
121 |
0 |
parserContext.registerComponent(new BeanComponentDefinition(definition, id)); |
122 |
|
} |
123 |
|
} |
124 |
|
} |
125 |
|
} |
126 |
53 |
if (!createdBeanPostProcessor) { |
127 |
|
|
128 |
45 |
Element childElement = element.getOwnerDocument().createElement("beanPostProcessor"); |
129 |
45 |
element.appendChild(childElement); |
130 |
45 |
createBeanPostProcessor(parserContext, contextId, childElement); |
131 |
|
} |
132 |
53 |
} |
133 |
|
}); |
134 |
|
|
135 |
50 |
registerParser("xpath", new BeanDefinitionParser(XPathBuilder.class) { |
136 |
|
@Override |
137 |
50 |
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { |
138 |
|
|
139 |
0 |
String xpath = DomUtils.getTextValue(element); |
140 |
0 |
builder.addConstructorArg(xpath); |
141 |
0 |
super.doParse(element, parserContext, builder); |
142 |
0 |
builder.addPropertyValue("namespacesFromDom", element); |
143 |
0 |
} |
144 |
|
}); |
145 |
50 |
} |
146 |
|
|
147 |
|
protected void createBeanPostProcessor(ParserContext parserContext, String contextId, Element childElement) { |
148 |
53 |
String beanPostProcessorId = contextId + ":beanPostProcessor"; |
149 |
53 |
childElement.setAttribute("id", beanPostProcessorId); |
150 |
53 |
BeanDefinition definition = beanPostProcessorParser.parse(childElement, parserContext); |
151 |
53 |
definition.getPropertyValues().addPropertyValue("camelContext", new RuntimeBeanReference(contextId)); |
152 |
53 |
} |
153 |
|
|
154 |
|
protected void registerScriptParser(String elementName, String engineName) { |
155 |
0 |
registerParser(elementName, new ScriptDefinitionParser(engineName)); |
156 |
0 |
} |
157 |
|
|
158 |
|
protected void registerParser(String name, org.springframework.beans.factory.xml.BeanDefinitionParser parser) { |
159 |
250 |
parserElementNames.add(name); |
160 |
250 |
registerBeanDefinitionParser(name, parser); |
161 |
250 |
} |
162 |
|
|
163 |
|
public Set<String> getParserElementNames() { |
164 |
0 |
return parserElementNames; |
165 |
|
} |
166 |
|
|
167 |
|
protected Object parseUsingJaxb(Element element, ParserContext parserContext) { |
168 |
|
try { |
169 |
53 |
Unmarshaller unmarshaller = getJaxbContext().createUnmarshaller(); |
170 |
53 |
return unmarshaller.unmarshal(element); |
171 |
0 |
} catch (JAXBException e) { |
172 |
0 |
throw new BeanDefinitionStoreException("Failed to parse JAXB element: " + e, e); |
173 |
|
} |
174 |
|
} |
175 |
|
|
176 |
|
protected JAXBContext getJaxbContext() throws JAXBException { |
177 |
53 |
if (jaxbContext == null) { |
178 |
50 |
jaxbContext = JAXBContext.newInstance(JAXB_PACKAGES); |
179 |
|
} |
180 |
53 |
return jaxbContext; |
181 |
|
} |
182 |
|
} |