MessageListenerContainerObjectDefinitionParser.cs :  » Inversion-of-Control-Dependency-Injection » Spring.net » Spring » Messaging » Nms » Config » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Inversion of Control Dependency Injection » Spring.net 
Spring.net » Spring » Messaging » Nms » Config » MessageListenerContainerObjectDefinitionParser.cs
#region License

/*
 * Copyright 2002-2008 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#endregion

using System;
using System.Xml;
using Apache.NMS;
using Spring.Core.TypeResolution;
using Spring.Messaging.Nms.Listener;
using Spring.Messaging.Nms.Listener.Adapter;
using Spring.Objects.Factory.Config;
using Spring.Objects.Factory.Support;
using Spring.Objects.Factory.Xml;
using Spring.Util;

namespace Spring.Messaging.Nms.Config{
    /// <summary>
    /// Parser for the NMS <code>&lt;listener-container&gt;</code> element.
    /// </summary>
    /// <author>Mark Fisher</author>
    /// <author>Juergen Hoeller</author>
    /// <author>Mark Pollack (.NET)</author>
    public class MessageListenerContainerObjectDefinitionParser : IObjectDefinitionParser
    {
        #region Fields

        private readonly string LISTENER_ELEMENT = "listener";

        private readonly string ID_ATTRIBUTE = "id";

        private readonly string DESTINATION_ATTRIBUTE = "destination";

        private readonly string SUBSCRIPTION_ATTRIBUTE = "subscription";

        private readonly string SELECTOR_ATTRIBUTE = "selector";

        private readonly string REF_ATTRIBUTE = "ref";

        private readonly string METHOD_ATTRIBUTE = "method";

        private readonly string DESTINATION_RESOLVER_ATTRIBUTE = "destination-resolver";

        private readonly string MESSAGE_CONVERTER_ATTRIBUTE = "message-converter";

        private readonly string RESPONSE_DESTINATION_ATTRIBUTE = "response-destination";

        private readonly string DESTINATION_TYPE_ATTRIBUTE = "destination-type";

        private readonly string DESTINATION_TYPE_QUEUE = "queue";

        private readonly string DESTINATION_TYPE_TOPIC = "topic";

        private readonly string DESTINATION_TYPE_DURABLE_TOPIC = "durableTopic";

        private readonly string CLIENT_ID_ATTRIBUTE = "client-id";

        private readonly string ACKNOWLEDGE_ATTRIBUTE = "acknowledge";

        private readonly string ACKNOWLEDGE_AUTO = "auto";

        private readonly string ACKNOWLEDGE_CLIENT = "client";

        private readonly string ACKNOWLEDGE_DUPS_OK = "dups-ok";

        private readonly string ACKNOWLEDGE_TRANSACTED = "transacted";

        private readonly string CONCURRENCY_ATTRIBUTE = "concurrency";

        private readonly string RECOVERY_INTERVAL_ATTRIBUTE = "recovery-interval";

        private readonly string MAX_RECOVERY_TIME_ATTRIBUTE = "max-recovery-time"; 
        
        private readonly string CONNECTION_FACTORY_ATTRIBUTE = "connection-factory";

        private readonly string CONTAINER_CUSTOM_TYPE = "container-custom-type";

        private readonly string PUBSUB_DOMAIN_ATTRIBUTE = "pubsub-domain";

        private readonly string AUTO_STARTUP = "auto-startup";

        private readonly string ERROR_HANDLER_ATTRIBUTE = "error-handler";

        private readonly string EXCEPTION_LISTENER_ATTRIBUTE = "exception-listener";
        
        #endregion

        #region IObjectDefinitionParser Members

        /// <summary>
        /// Parse the specified XmlElement and register the resulting
        /// ObjectDefinitions with the <see cref="ParserContext.Registry"/> IObjectDefinitionRegistry
        /// embedded in the supplied <see cref="ParserContext"/>
        /// </summary>
        /// <param name="element">The element to be parsed.</param>
        /// <param name="parserContext">TThe object encapsulating the current state of the parsing process.
        /// Provides access to a IObjectDefinitionRegistry</param>
        /// <returns>The primary object definition.</returns>
        /// <remarks>
        ///   <p>
        /// This method is never invoked if the parser is namespace aware
        /// and was called to process the root node.
        /// </p>
        /// </remarks>
        public IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext)
        {

            XmlNodeList childNodes = element.ChildNodes;
            foreach (XmlNode childNode in childNodes)
            {
                if (childNode.NodeType == XmlNodeType.Element)
                {
                    string localName = childNode.LocalName;
                    if (LISTENER_ELEMENT.Equals(localName))
                    {
                        ParseListener((XmlElement) childNode, element, parserContext);
                    }
                }
            }
            return null;
        }

        #endregion

        private void ParseListener(XmlElement listenerElement, XmlElement containerElement, ParserContext parserContext)
        {
            ObjectDefinitionBuilder listenerDefBuilder =
                parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(typeof (MessageListenerAdapter));

            string reference = listenerElement.GetAttribute(REF_ATTRIBUTE);
            if (!StringUtils.HasText(reference))
            {
                parserContext.ReaderContext.ReportException(listenerElement, LISTENER_ELEMENT,
                                                            "Listener '" + REF_ATTRIBUTE +
                                                            "' attribute contains empty value.");
            }
            listenerDefBuilder.AddPropertyValue("HandlerObject", new RuntimeObjectReference(reference));

            string handlerMethod = null;
            if (listenerElement.HasAttribute(METHOD_ATTRIBUTE))
            {
                handlerMethod = listenerElement.GetAttribute(METHOD_ATTRIBUTE);
                {
                    if (!StringUtils.HasText(handlerMethod))
                    {
                        parserContext.ReaderContext.ReportException(listenerElement, LISTENER_ELEMENT,
                                                                    "Listener '" + METHOD_ATTRIBUTE +
                                                                    "' attribute contains empty value.");
                    }
                }               
            }
            listenerDefBuilder.AddPropertyValue("DefaultHandlerMethod", handlerMethod);

            if (containerElement.HasAttribute(MESSAGE_CONVERTER_ATTRIBUTE))
            {
                string messageConverter = containerElement.GetAttribute(MESSAGE_CONVERTER_ATTRIBUTE);
                listenerDefBuilder.AddPropertyValue("MessageConverter", new RuntimeObjectReference(messageConverter));
            }

            ObjectDefinitionBuilder containerDefBuilder = ParseContainer(listenerElement, containerElement, parserContext);

            if (listenerElement.HasAttribute(RESPONSE_DESTINATION_ATTRIBUTE))
            {
                string responseDestination = listenerElement.GetAttribute(RESPONSE_DESTINATION_ATTRIBUTE);
                bool pubSubDomain = IndicatesPubSub(containerDefBuilder.RawObjectDefinition);
                listenerDefBuilder.AddPropertyValue(pubSubDomain ? "DefaultResponseTopicName" : "DefaultResponseQueueName",
                                             responseDestination);
                if (containerDefBuilder.RawObjectDefinition.PropertyValues.Contains("DestinationResolver"))
                {
                    listenerDefBuilder.AddPropertyValue("DestinationResolver",
                                                 containerDefBuilder.RawObjectDefinition.PropertyValues.GetPropertyValue
                                                     (
                                                     "DestinationResolver").Value);
                }
            }

            containerDefBuilder.AddPropertyValue("MessageListener", listenerDefBuilder.ObjectDefinition);

            string containerObjectName = listenerElement.GetAttribute(ID_ATTRIBUTE);
            // If no object id is given auto generate one using the ReaderContext's ObjectNameGenerator 
            if (!StringUtils.HasText(containerObjectName))
            {
                containerObjectName =
                    parserContext.ReaderContext.GenerateObjectName(containerDefBuilder.RawObjectDefinition);
            }

            string pubsubDomain = listenerElement.GetAttribute(PUBSUB_DOMAIN_ATTRIBUTE);
            containerDefBuilder.AddPropertyValue("PubSubDomain", pubsubDomain);


            parserContext.Registry.RegisterObjectDefinition(containerObjectName, containerDefBuilder.ObjectDefinition);
        }

        private ObjectDefinitionBuilder ParseContainer(XmlElement listenerElement, XmlElement containerElement,
                                                       ParserContext parserContext)
        {
            //Only support SimpleMessageListenerContainer or container-custom-type

            Type containerType = typeof (SimpleMessageListenerContainer);
            if (containerElement.HasAttribute(CONTAINER_CUSTOM_TYPE))
            {
                string customType = containerElement.GetAttribute(CONTAINER_CUSTOM_TYPE);
                if (!StringUtils.HasLength(customType))
                {
                    parserContext.ReaderContext.ReportException(containerElement, CONTAINER_CUSTOM_TYPE,
                                            "Listener container '" + CONTAINER_CUSTOM_TYPE +
                                            "' attribute contains empty value.");
                }
                try
                {
                    containerType = TypeResolutionUtils.ResolveType(customType);
                } catch (Exception ex)
                {
                    parserContext.ReaderContext.ReportException(containerElement, CONTAINER_CUSTOM_TYPE,
                            "Invalid container-custom-type value [" + customType + "]", ex);
                }
            }            

            ObjectDefinitionBuilder containerDef =
                    parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(containerType);

            ParseListenerConfiguration(listenerElement, parserContext, containerDef);
            ParseContainerConfiguration(containerElement, parserContext, containerDef);


            if (containerElement.HasAttribute(AUTO_STARTUP))
            {
                string autoStartup = containerElement.GetAttribute(AUTO_STARTUP);
                if (StringUtils.HasText(autoStartup))
                {
                    containerDef.AddPropertyValue("AutoStartup", autoStartup);
                }
            }

            string connectionFactoryObjectName = "connectionFactory";
            if (containerElement.HasAttribute(CONNECTION_FACTORY_ATTRIBUTE))
            {
                connectionFactoryObjectName = containerElement.GetAttribute(CONNECTION_FACTORY_ATTRIBUTE);
                if (!StringUtils.HasText(connectionFactoryObjectName))
                {
                    parserContext.ReaderContext.ReportException(listenerElement, LISTENER_ELEMENT,
                                                                "Listener container '" + CONNECTION_FACTORY_ATTRIBUTE +
                                                                "' attribute contains empty value.");
                }

            }

            containerDef.AddPropertyValue("ConnectionFactory", new RuntimeObjectReference(connectionFactoryObjectName));


            string errorHandlerObjectName = containerElement.GetAttribute(ERROR_HANDLER_ATTRIBUTE);
            if (StringUtils.HasText(errorHandlerObjectName))
            {
                containerDef.AddPropertyValue("ErrorHandler",
                                              new RuntimeObjectReference(errorHandlerObjectName));
            }

            string exceptionListenerObjectName = containerElement.GetAttribute(EXCEPTION_LISTENER_ATTRIBUTE);
            if (StringUtils.HasText(exceptionListenerObjectName))
            {
                containerDef.AddPropertyValue("ExceptionListener",
                                              new RuntimeObjectReference(exceptionListenerObjectName));
            }

            string destinationResolverObjectName = containerElement.GetAttribute(DESTINATION_RESOLVER_ATTRIBUTE);
            if (StringUtils.HasText(destinationResolverObjectName))
            {
                containerDef.AddPropertyValue("DestinationResolver",
                                              new RuntimeObjectReference(destinationResolverObjectName));
            }

            string acknowledge = containerElement.GetAttribute(ACKNOWLEDGE_ATTRIBUTE);
            if (StringUtils.HasText(acknowledge))
            {
                AcknowledgementMode acknowledgementMode = ParseAcknowledgementMode(containerElement, parserContext);
                containerDef.AddPropertyValue("SessionAcknowledgeMode", acknowledgementMode);
            }

            string concurrency = ParseConcurrency(containerElement, parserContext);
            if (concurrency != null)
            {
                containerDef.AddPropertyValue("ConcurrentConsumers", concurrency);
            }
            containerDef.AddPropertyValue("RecoveryInterval", ParseRecoveryInterval(containerElement, parserContext));

            containerDef.AddPropertyValue("MaxRecoveryTime", ParseMaxRecoveryTime(containerElement, parserContext));             

            return containerDef;
        }

        private bool IndicatesPubSub(AbstractObjectDefinition configDef)
        {
            return (bool) configDef.PropertyValues.GetPropertyValue("PubSubDomain").Value;
        }

        private void ParseListenerConfiguration(XmlElement ele, ParserContext parserContext,
                                                ObjectDefinitionBuilder containerDef)
        {
            string destination = ele.GetAttribute(DESTINATION_ATTRIBUTE);
            if (!StringUtils.HasText(destination))
            {
                parserContext.ReaderContext.ReportException(ele, LISTENER_ELEMENT,
                                                            "Listener '" + DESTINATION_ATTRIBUTE +
                                                            "' attribute contains empty value.");
            }
            containerDef.AddPropertyValue("DestinationName", destination);

            if (ele.HasAttribute(SUBSCRIPTION_ATTRIBUTE))
            {
                string subscription = ele.GetAttribute(SUBSCRIPTION_ATTRIBUTE);
                if (!StringUtils.HasText(subscription))
                {
                    parserContext.ReaderContext.ReportException(ele, SUBSCRIPTION_ATTRIBUTE,
                                                                "Listener '" + SUBSCRIPTION_ATTRIBUTE +
                                                                "' attribute contains empty value.");
                }
                containerDef.AddPropertyValue("DurableSubscriptionName", subscription);
            }

            if (ele.HasAttribute(SELECTOR_ATTRIBUTE))
            {
                string selector = ele.GetAttribute(SELECTOR_ATTRIBUTE);
                if (!StringUtils.HasText(selector))
                {
                    parserContext.ReaderContext.ReportException(ele, selector,
                                                                "Listener '" + SELECTOR_ATTRIBUTE +
                                                                "' attribute contains empty value.");
                }
                containerDef.AddPropertyValue("MessageSelector", selector);
            }
        }

        private void ParseContainerConfiguration(XmlElement ele, ParserContext parserContext,
                                                 ObjectDefinitionBuilder containerDef)
        {
            string destinationType = ele.GetAttribute(DESTINATION_TYPE_ATTRIBUTE);
            bool pubSubDomain = false;
            bool subscriptionDurable = false;
            if (DESTINATION_TYPE_DURABLE_TOPIC.Equals(destinationType))
            {
                pubSubDomain = true;
                subscriptionDurable = true;
            }
            else if (DESTINATION_TYPE_TOPIC.Equals(destinationType))
            {
                pubSubDomain = true;
            }
            else if ("".Equals(destinationType) || DESTINATION_TYPE_QUEUE.Equals(destinationType))
            {
                // the default: queue
            }
            else
            {
                parserContext.ReaderContext.ReportException(ele, destinationType,
                                                            "Invalid listener container '" + DESTINATION_TYPE_ATTRIBUTE +
                                                            "': only 'queue', 'topic' and 'durableTopic' supported");
            }

            containerDef.AddPropertyValue("PubSubDomain", pubSubDomain);
            containerDef.AddPropertyValue("SubscriptionDurable", subscriptionDurable);

            if (ele.HasAttribute(CLIENT_ID_ATTRIBUTE))
            {
                string clientId = ele.GetAttribute(CLIENT_ID_ATTRIBUTE);
                if (!StringUtils.HasText(clientId))
                {
                    parserContext.ReaderContext.ReportException(ele, clientId,
                                                                "Listener '" + CLIENT_ID_ATTRIBUTE +
                                                                "' attribute contains empty value.");
                }
                containerDef.AddPropertyValue("ClientId", clientId);
            }
        }

        private AcknowledgementMode ParseAcknowledgementMode(XmlElement element, ParserContext parserContext)
        {
            string acknowledge = element.GetAttribute(ACKNOWLEDGE_ATTRIBUTE);
            if (acknowledge.Equals(ACKNOWLEDGE_TRANSACTED))
            {
                return AcknowledgementMode.Transactional;
            }
            else if (acknowledge.Equals(ACKNOWLEDGE_DUPS_OK))
            {
                return AcknowledgementMode.DupsOkAcknowledge;
            }
            else if (acknowledge.Equals(ACKNOWLEDGE_CLIENT))
            {
                return AcknowledgementMode.ClientAcknowledge;
            }
            else if (!acknowledge.Equals(ACKNOWLEDGE_AUTO))
            {
                parserContext.ReaderContext.ReportException(element, ACKNOWLEDGE_ATTRIBUTE,
                                                            "Invalid listener container 'acknowledge' setting ['" +
                                                            acknowledge +
                                                            "]: only \"auto\", \"client\", \"dups-ok\" and \"transacted\" supported.");
            }
            return AcknowledgementMode.AutoAcknowledge;
        }

        private string ParseConcurrency(XmlElement ele, ParserContext parserContext)
        {
            string concurrency = ele.GetAttribute(CONCURRENCY_ATTRIBUTE);
            if (!StringUtils.HasText(concurrency))
            {
                return null;
            } else
            {
                return concurrency;
            }            
        }

        private string ParseRecoveryInterval(XmlElement ele, ParserContext parserContext)
        {
            string recoveryInterval = ele.GetAttribute(RECOVERY_INTERVAL_ATTRIBUTE);
            if (StringUtils.HasText(recoveryInterval))
            {
                return recoveryInterval;
                
            } else
            {
                return SimpleMessageListenerContainer.DEFAULT_RECOVERY_INTERVAL;
            }
        }

        private string ParseMaxRecoveryTime(XmlElement ele, ParserContext parserContext)
        {
            string recoverTime = ele.GetAttribute(MAX_RECOVERY_TIME_ATTRIBUTE);
            if (StringUtils.HasText(recoverTime))
            {
                return recoverTime;
            }
            else
            {
                return SimpleMessageListenerContainer.DEFAULT_MAX_RECOVERY_TIME;
            }
        }
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.