001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.spring.handler;
018    
019    import org.w3c.dom.Attr;
020    import org.w3c.dom.Element;
021    import org.w3c.dom.NamedNodeMap;
022    import org.w3c.dom.Node;
023    import org.w3c.dom.NodeList;
024    
025    import org.apache.camel.processor.RedeliveryPolicy;
026    import org.apache.camel.spring.ErrorHandlerType;
027    import org.apache.camel.util.ObjectHelper;
028    import org.springframework.beans.factory.config.BeanDefinition;
029    import org.springframework.beans.factory.support.BeanDefinitionBuilder;
030    import org.springframework.beans.factory.xml.ParserContext;
031    import org.springframework.util.Assert;
032    import org.springframework.util.StringUtils;
033    
034    /**
035     * The DefinitionParser to deal with the ErrorHandler
036     */
037    public class ErrorHandlerDefinitionParser extends BeanDefinitionParser {
038        protected BeanDefinitionParser redeliveryPolicyParser = new RedeliveryPolicyDefinitionParser(RedeliveryPolicy.class);
039        
040        public ErrorHandlerDefinitionParser() {
041            // need to override the default
042            super(null, false);
043        }
044    
045        protected Class getBeanClass(Element element) {
046            ErrorHandlerType type = ErrorHandlerType.DefaultErrorHandler;
047    
048            if (ObjectHelper.isNotEmpty(element.getAttribute("type"))) {
049                type = ErrorHandlerType.valueOf(element.getAttribute("type"));
050            }
051            return type.getTypeAsClass();
052        }
053        
054        protected boolean isEligibleAttribute(String attributeName) {
055            if (attributeName == null || ID_ATTRIBUTE.equals(attributeName)) {
056                return false;
057            }
058            return !attributeName.equals("xmlns") && !attributeName.startsWith("xmlns:")
059                    && !attributeName.equals("type")
060                    && !attributeName.equals("onRedeliveryRef")
061                    && !attributeName.equals("onRetryWhileRef")
062                    && !attributeName.equals("transactionTemplateRef")
063                    && !attributeName.equals("transactionManagerRef");
064        }
065    
066        @Override
067        protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
068            super.doParse(element, parserContext, builder);
069            ErrorHandlerType type = ErrorHandlerType.DefaultErrorHandler;
070            if (ObjectHelper.isNotEmpty(element.getAttribute("type"))) {
071                type = ErrorHandlerType.valueOf(element.getAttribute("type"));
072            }
073            if (type.equals(ErrorHandlerType.NoErrorHandler) || type.equals(ErrorHandlerType.LoggingErrorHandler)) {
074                // don't need to parser other stuff
075                return;
076            }
077            if (type.equals(ErrorHandlerType.DefaultErrorHandler) 
078                || type.equals(ErrorHandlerType.DeadLetterChannel) 
079                || type.equals(ErrorHandlerType.TransactionErrorHandler)) {
080                NodeList list = element.getChildNodes();
081                int size = list.getLength();
082                for (int i = 0; i < size; i++) {
083                    Node child = list.item(i);
084                    if (child instanceof Element) {
085                        Element childElement = (Element)child;
086                        String localName = child.getLocalName();
087                        // set the redeliveryPolicy
088                        if (localName.equals("redeliveryPolicy")) {
089                            BeanDefinition redeliveryPolicyDefinition = redeliveryPolicyParser.parse(childElement, parserContext);
090                            builder.addPropertyValue(localName, redeliveryPolicyDefinition);
091                        }
092                    }
093                }
094                parserRefAttribute(element, "onRedeliveryRef", "onRedelivery", builder);
095            }
096            if (type.equals(ErrorHandlerType.TransactionErrorHandler)) {
097                // deal with transactionTemplateRef
098                parserRefAttribute(element, "transactionTemplateRef", "transactionTemplate", builder);
099                parserRefAttribute(element, "transactionManagerRef", "transactionManager", builder);
100            }
101        }
102    
103        private void parserRefAttribute(Element element, String attributeName, String propertyName, BeanDefinitionBuilder builder) {
104            NamedNodeMap attributes = element.getAttributes();
105            for (int x = 0; x < attributes.getLength(); x++) {
106                Attr attribute = (Attr) attributes.item(x);
107                String name = attribute.getLocalName();
108                if (name.equals(attributeName)) {
109                    Assert.state(StringUtils.hasText(propertyName),
110                            "Illegal property name returned from 'extractPropertyName(String)': cannot be null or empty.");
111                    builder.addPropertyReference(propertyName, attribute.getValue());
112                }
113            }
114        }
115        
116        protected class RedeliveryPolicyDefinitionParser extends BeanDefinitionParser {
117    
118            public RedeliveryPolicyDefinitionParser(Class type) {
119                super(type, false);
120            }
121    
122            protected boolean shouldGenerateId() {
123                return true;
124            }
125        }
126        
127    }