Coverage Report - org.apache.camel.spring.handler.CamelNamespaceHandler
 
Classes in this File Line Coverage Branch Coverage Complexity
CamelNamespaceHandler
76% 
79% 
0
 
 1  
 /**
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 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  
                 // lets avoid folks having to explicitly give an ID to a camel
 73  
                 // context
 74  53
                 if (ObjectHelper.isNullOrBlank(contextId)) {
 75  7
                     contextId = "camelContext";
 76  7
                     element.setAttribute("id", contextId);
 77  
                 }
 78  
 
 79  
                 // now lets parse the routes
 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  
                                 // TODO we can zap this?
 106  11
                                 definition.getPropertyValues().addPropertyValue("context", new RuntimeBeanReference(contextId));
 107  
                                 // definition.getPropertyValues().addPropertyValue("context",
 108  
                                 // builder.getBeanDefinition());
 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  
                     // no bean processor element so lets add a fake one
 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  
                 // lets create a child context
 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  
 }