예제 #1
0
        private static Pair <String, XPathResultType> MakeAttributeProperty(SchemaItemAttribute attribute, Property property, XPathNamespaceContext ctx)
        {
            var prefix = ctx.LookupPrefix(attribute.Namespace);

            if (String.IsNullOrEmpty(prefix))
            {
                prefix = "";
            }
            else
            {
                prefix += ':';
            }

            if (IsAnySimpleProperty(property))
            {
                XPathResultType type = SchemaUtil.SimpleTypeToResultType(attribute.SimpleType);
                String          path = "/@" + prefix + property.PropertyNameAtomic;
                return(new Pair <String, XPathResultType>(path, type));
            }

            if (IsAnyMappedProperty(property))
            {
                throw new Exception("Mapped properties not applicable to attributes");
            }

            throw new Exception("Indexed properties not applicable to attributes");
        }
예제 #2
0
        public Object Get(EventBean eventBean)
        {
            var und = eventBean.Underlying;

            if (und == null)
            {
                throw new PropertyAccessException(
                          "Unexpected null underlying event encountered, expecting System.Xml.XmlNode instance as underlying");
            }

            XPathNavigator navigator;

            var xnode = und as XElement;

            if (xnode == null)
            {
                var node = und as XmlNode;
                if (node == null)
                {
                    throw new PropertyAccessException("Unexpected underlying event of type '" + und.GetType().FullName +
                                                      "' encountered, expecting System.Xml.XmlNode as underlying");
                }

                if (Log.IsDebugEnabled)
                {
                    Log.Debug(
                        "Running XPath '{0}' for property '{1}' against Node XML : {2}",
                        _expressionText,
                        _property,
                        SchemaUtil.Serialize((XmlNode)und));
                }

                navigator = node.CreateNavigator();
            }
            else
            {
                navigator = xnode.CreateNavigator();
            }

            return(EvaluateXPathGet(
                       navigator, _expression, _expressionText,
                       _property, _optionalCastToType, _resultType,
                       _isCastToArray, _simpleTypeParser));
        }
예제 #3
0
        private static Pair <String, XPathResultType> MakeProperty(SchemaElementComplex parent, Property property, XPathNamespaceContext ctx, bool isLast, bool isDynamic, String defaultNamespacePrefix)
        {
            var text = property.PropertyNameAtomic;
            var obj  = SchemaUtil.FindPropertyMapping(parent, text);

            if ((obj is SchemaElementSimple) || (obj is SchemaElementComplex))
            {
                return(MakeElementProperty((SchemaElement)obj, property, ctx, isLast, isDynamic, defaultNamespacePrefix));
            }
            if (obj != null)
            {
                return(MakeAttributeProperty((SchemaItemAttribute)obj, property, ctx));
            }
            if (isDynamic)
            {
                return(MakeElementProperty(null, property, ctx, isLast, isDynamic, defaultNamespacePrefix));
            }

            return(null);
        }
예제 #4
0
        private Type DoResolvePropertyType(String propertyExpression, bool allowSimpleProperties)
        {
            // see if this is an indexed property
            int index = ASTUtil.UnescapedIndexOfDot(propertyExpression);

            if ((!allowSimpleProperties) && (index == -1))
            {
                // parse, can be an indexed property
                Property property = PropertyParser.ParseAndWalkLaxToSimple(propertyExpression);
                if (!property.IsDynamic)
                {
                    if (!(property is IndexedProperty))
                    {
                        return(null);
                    }
                    var indexedProp = (IndexedProperty)property;
                    EventPropertyDescriptor descriptor = PropertyDescriptorMap.Get(indexedProp.PropertyNameAtomic);
                    if (descriptor == null)
                    {
                        return(null);
                    }
                    return(descriptor.PropertyType);
                }
            }

            Property prop = PropertyParser.ParseAndWalkLaxToSimple(propertyExpression);

            if (prop.IsDynamic)
            {
                return(typeof(XmlNode));
            }

            SchemaItem item = prop.GetPropertyTypeSchema(_schemaModelRoot, EventAdapterService);

            if (item == null)
            {
                return(null);
            }

            return(SchemaUtil.ToReturnType(item));
        }
예제 #5
0
        /// <summary>
        /// Return the xPath corresponding to the given property. The PropertyName String
        /// may be simple, nested, indexed or mapped.
        /// </summary>
        /// <param name="propertyName">is the event property name</param>
        /// <param name="namespace">is the default namespace</param>
        /// <param name="schemaModel">is the schema model</param>
        /// <param name="xPathContext">is the xpath factory instance to use</param>
        /// <param name="rootElementName">is the name of the root element</param>
        /// <param name="eventAdapterService">for type lookup and creation</param>
        /// <param name="xmlEventType">the resolving type</param>
        /// <param name="isAllowFragment">whether fragmenting is allowed</param>
        /// <param name="defaultNamespace">default namespace</param>
        /// <returns>
        /// xpath expression
        /// </returns>
        /// <throws>EPException is there are XPath errors</throws>
        public static EventPropertyGetter GetXPathResolution(String propertyName,
                                                             XPathNamespaceContext xPathContext,
                                                             String rootElementName,
                                                             String @namespace,
                                                             SchemaModel schemaModel,
                                                             EventAdapterService eventAdapterService,
                                                             BaseXMLEventType xmlEventType,
                                                             bool isAllowFragment,
                                                             String defaultNamespace)
        {
            if (Log.IsDebugEnabled)
            {
                Log.Debug("Determining XPath expression for property '" + propertyName + "'");
            }

            var ctx        = new XPathNamespaceContext();
            var namespaces = schemaModel.Namespaces;

            string defaultNamespacePrefix = null;

            for (int i = 0; i < namespaces.Count; i++)
            {
                var namespacePrefix = "n" + i;
                ctx.AddNamespace(namespacePrefix, namespaces[i]);
                if ((defaultNamespace != null) && (defaultNamespace == namespaces[i]))
                {
                    defaultNamespacePrefix = namespacePrefix;
                }
            }

            Property property  = PropertyParser.ParseAndWalk(propertyName);
            var      isDynamic = property.IsDynamic;

            var    rootComplexElement = SchemaUtil.FindRootElement(schemaModel, @namespace, rootElementName);
            string prefix             = ctx.LookupPrefix(rootComplexElement.Namespace);

            if (prefix == null)
            {
                prefix = "";
            }
            else
            {
                prefix += ':';
            }

            var xPathBuf = new StringBuilder();

            xPathBuf.Append('/');
            xPathBuf.Append(prefix);
            if (rootElementName.StartsWith("//"))
            {
                xPathBuf.Append(rootElementName.Substring(2));
            }
            else
            {
                xPathBuf.Append(rootElementName);
            }

            var parentComplexElement            = rootComplexElement;
            Pair <String, XPathResultType> pair = null;

            if (!(property is NestedProperty))
            {
                pair = MakeProperty(rootComplexElement, property, ctx, true, isDynamic, defaultNamespacePrefix);
                if (pair == null)
                {
                    throw new PropertyAccessException("Failed to locate property '" + propertyName + "' in schema");
                }
                xPathBuf.Append(pair.First);
            }
            else
            {
                NestedProperty nestedProperty = (NestedProperty)property;
                int            indexLast      = nestedProperty.Properties.Count - 1;

                for (int i = 0; i < indexLast + 1; i++)
                {
                    var isLast         = i == indexLast;
                    var propertyNested = nestedProperty.Properties[i];
                    pair = MakeProperty(parentComplexElement, propertyNested, ctx, isLast, isDynamic, defaultNamespacePrefix);
                    if (pair == null)
                    {
                        throw new PropertyAccessException("Failed to locate property '" + propertyName + "' nested property part '" + property.PropertyNameAtomic + "' in schema");
                    }

                    var text = propertyNested.PropertyNameAtomic;
                    var obj  = SchemaUtil.FindPropertyMapping(parentComplexElement, text);
                    if (obj is SchemaElementComplex)
                    {
                        parentComplexElement = (SchemaElementComplex)obj;
                    }
                    xPathBuf.Append(pair.First);
                }
            }

            var xPath = xPathBuf.ToString();

            if ((ExecutionPathDebugLog.IsEnabled) && (Log.IsDebugEnabled))
            {
                Log.Debug(".parse XPath for property '" + propertyName + "' is expression=" + xPath);
            }

            // Compile assembled XPath expression
            if (Log.IsDebugEnabled)
            {
                Log.Debug("Compiling XPath expression '" + xPath + "' for property '" + propertyName + "' using namespace context :" + ctx);
            }

            XPathExpression expr;

            try
            {
                expr = XPathExpression.Compile(xPath, ctx);
            }
            catch (XPathException e) {
                String detail = "Error constructing XPath expression from property expression '" + propertyName + "' expression '" + xPath + "'";
                if (e.Message != null)
                {
                    throw new EPException(detail + " :" + e.Message, e);
                }
                throw new EPException(detail, e);
            }

            // get type
            var item = property.GetPropertyTypeSchema(rootComplexElement, eventAdapterService);

            if ((item == null) && (!isDynamic))
            {
                return(null);
            }

            var resultType = isDynamic ? typeof(XmlNode) : SchemaUtil.ToReturnType(item);

            FragmentFactory fragmentFactory = null;

            if (isAllowFragment)
            {
                fragmentFactory = new FragmentFactoryDOMGetter(eventAdapterService, xmlEventType, propertyName);
            }

            return(new XPathPropertyGetter(propertyName, xPath, expr, pair.Second, resultType, fragmentFactory));
        }
예제 #6
0
        private static Pair <String, XPathResultType> MakeElementProperty(SchemaElement schemaElement, Property property, XPathNamespaceContext ctx, bool isAlone, bool isDynamic, String defaultNamespacePrefix)
        {
            XPathResultType type;

            if (isDynamic)
            {
                type = XPathResultType.Any;
            }
            else if (schemaElement is SchemaElementSimple)
            {
                var element = (SchemaElementSimple)schemaElement;
                type = SchemaUtil.SimpleTypeToResultType(element.SimpleType);
            }
            else
            {
                var complex = (SchemaElementComplex)schemaElement;
                type = XPathResultType.Any;
                //if (complex.OptionalSimpleType != null)
                //{
                //    type = SchemaUtil.SimpleTypeToQName(complex.OptionalSimpleType);
                //}
                //else
                //{
                //    // The result is a node
                //    type = XPathResultType.Any;
                //}
            }

            var prefix = isDynamic ? defaultNamespacePrefix : ctx.LookupPrefix(schemaElement.Namespace);

            if (String.IsNullOrEmpty(prefix))
            {
                prefix = String.Empty;
            }
            else
            {
                prefix += ':';
            }

            if (IsAnySimpleProperty(property))
            {
                if (!isDynamic && schemaElement.IsArray && !isAlone)
                {
                    throw new PropertyAccessException("Simple property not allowed in repeating elements at '" + schemaElement.Name + "'");
                }
                return(new Pair <String, XPathResultType>('/' + prefix + property.PropertyNameAtomic, type));
            }

            if (IsAnyMappedProperty(property))
            {
                if (!isDynamic && !schemaElement.IsArray)
                {
                    throw new PropertyAccessException("Element " + property.PropertyNameAtomic + " is not a collection, cannot be used as mapped property");
                }
                String key = GetMappedPropertyKey(property);
                return(new Pair <String, XPathResultType>('/' + prefix + property.PropertyNameAtomic + "[@id='" + key + "']", type));
            }

            if (!isDynamic && !schemaElement.IsArray)
            {
                throw new PropertyAccessException("Element " + property.PropertyNameAtomic + " is not a collection, cannot be used as mapped property");
            }
            int index         = GetIndexedPropertyIndex(property);
            int xPathPosition = index + 1;

            return(new Pair <String, XPathResultType>('/' + prefix + property.PropertyNameAtomic + "[position() = " + xPathPosition + ']', type));
        }
예제 #7
0
        /// <summary>
        /// Set the preconfigured event properties resolved by XPath expression.
        /// </summary>
        /// <param name="explicitXPathProperties">are preconfigured event properties</param>
        /// <param name="additionalSchemaProperties">the explicit properties</param>
        protected void Initialize(ICollection <ConfigurationEventTypeXMLDOM.XPathPropertyDesc> explicitXPathProperties,
                                  IList <ExplicitPropertyDescriptor> additionalSchemaProperties)
        {
            // make sure we override those explicitly provided with those derived from a metadataz
            var namedProperties = new LinkedHashMap <String, ExplicitPropertyDescriptor>();

            foreach (ExplicitPropertyDescriptor desc in additionalSchemaProperties)
            {
                namedProperties[desc.Descriptor.PropertyName] = desc;
            }

            String xPathExpression = null;

            try
            {
                foreach (ConfigurationEventTypeXMLDOM.XPathPropertyDesc property in explicitXPathProperties)
                {
                    xPathExpression = property.XPath;
                    if (Log.IsInfoEnabled)
                    {
                        Log.Info("Compiling XPath expression for property '" + property.Name + "' as '" +
                                 xPathExpression + "'");
                    }

                    var expressionContext = NamespaceContext ?? GetExtendedContext();
                    var expression        = XPathExpression.Compile(xPathExpression, expressionContext);

                    FragmentFactoryXPathPredefinedGetter fragmentFactory = null;

                    var isFragment = false;
                    if (property.OptionalEventTypeName != null)
                    {
                        fragmentFactory = new FragmentFactoryXPathPredefinedGetter(
                            EventAdapterService,
                            property.OptionalEventTypeName,
                            property.Name);
                        isFragment = true;
                    }

                    var getter = new XPathPropertyGetter(
                        property.Name,
                        xPathExpression,
                        expression,
                        property.ResultType,
                        property.OptionalCastToType,
                        fragmentFactory);
                    var returnType = SchemaUtil.ToReturnType(
                        property.ResultType,
                        property.OptionalCastToType.GetBoxedType());
                    var indexType = returnType.GetIndexType();
                    var isIndexed = indexType != null;

                    if (property.ResultType == XPathResultType.NodeSet)
                    {
                        isIndexed = true;
                    }

                    var desc = new EventPropertyDescriptor(
                        property.Name, returnType, indexType, false, false,
                        isIndexed, false, isFragment);
                    var @explicit = new ExplicitPropertyDescriptor(
                        desc, getter, isIndexed,
                        property.OptionalEventTypeName);

                    namedProperties[desc.PropertyName] = @explicit;
                }
            }
            catch (XPathException ex)
            {
                throw new EPException(
                          "XPath expression could not be compiled for expression '" + xPathExpression + '\'', ex);
            }

            Initialize(namedProperties.Values);

            // evaluate start and end timestamp properties if any
            _startTimestampPropertyName = ConfigurationEventTypeXMLDOM.StartTimestampPropertyName;
            _endTimestampPropertyName   = ConfigurationEventTypeXMLDOM.EndTimestampPropertyName;
            EventTypeUtility.ValidateTimestampProperties(this, _startTimestampPropertyName, _endTimestampPropertyName);
        }
예제 #8
0
        /// <summary>
        /// Ctor.
        /// </summary>
        /// <param name="eventTypeMetadata">event type metadata</param>
        /// <param name="eventTypeId">The event type id.</param>
        /// <param name="config">configuration for type</param>
        /// <param name="schemaModel">the schema representation</param>
        /// <param name="eventAdapterService">type lookup and registration</param>
        public SchemaXMLEventType(EventTypeMetadata eventTypeMetadata, int eventTypeId, ConfigurationEventTypeXMLDOM config, SchemaModel schemaModel, EventAdapterService eventAdapterService)
            : base(eventTypeMetadata, eventTypeId, config, eventAdapterService)
        {
            _propertyGetterCache       = new Dictionary <String, EventPropertyGetter>();
            _schemaModel               = schemaModel;
            _rootElementNamespace      = config.RootElementNamespace;
            _schemaModelRoot           = SchemaUtil.FindRootElement(schemaModel, _rootElementNamespace, RootElementName);
            _isPropertyExpressionXPath = config.IsXPathPropertyExpr;

            // Set of namespace context for XPath expressions
            var ctx = new XPathNamespaceContext();

            if (config.DefaultNamespace != null)
            {
                ctx.SetDefaultNamespace(config.DefaultNamespace);
            }

            foreach (var entry in config.NamespacePrefixes)
            {
                ctx.AddNamespace(entry.Key, entry.Value);
            }

            NamespaceContext = ctx;

            // add properties for the root element
            var additionalSchemaProps = new List <ExplicitPropertyDescriptor>();

            // Add a property for each complex child element
            foreach (SchemaElementComplex complex in _schemaModelRoot.ComplexElements)
            {
                var  propertyName          = complex.Name;
                var  returnType            = typeof(XmlNode);
                Type propertyComponentType = null;

                if (complex.OptionalSimpleType != null)
                {
                    returnType = SchemaUtil.ToReturnType(complex);
                }
                if (complex.IsArray)
                {
                    // We use XmlNode[] for arrays and NodeList for XPath-Expressions returning Nodeset
                    returnType            = typeof(XmlNode[]);
                    propertyComponentType = typeof(XmlNode);
                }

                bool isFragment = false;
                if (ConfigurationEventTypeXMLDOM.IsAutoFragment && (!ConfigurationEventTypeXMLDOM.IsXPathPropertyExpr))
                {
                    isFragment = CanFragment(complex);
                }

                var indexType = returnType.GetIndexType();
                var isIndexed = indexType != null;
                var getter    = DoResolvePropertyGetter(propertyName, true);
                var desc      = new EventPropertyDescriptor(propertyName, returnType, indexType, false, false, isIndexed, false, isFragment);
                var @explicit = new ExplicitPropertyDescriptor(desc, getter, false, null);
                additionalSchemaProps.Add(@explicit);
            }

            // Add a property for each simple child element
            foreach (SchemaElementSimple simple in _schemaModelRoot.SimpleElements)
            {
                var propertyName = simple.Name;
                var returnType   = SchemaUtil.ToReturnType(simple);
                var getter       = DoResolvePropertyGetter(propertyName, true);
                var indexType    = returnType.GetIndexType();
                var isIndexed    = indexType != null;
                var desc         = new EventPropertyDescriptor(propertyName, returnType, indexType, false, false, isIndexed, false, false);
                var @explicit    = new ExplicitPropertyDescriptor(desc, getter, false, null);
                additionalSchemaProps.Add(@explicit);
            }

            // Add a property for each attribute
            foreach (SchemaItemAttribute attribute in _schemaModelRoot.Attributes)
            {
                var propertyName = attribute.Name;
                var returnType   = SchemaUtil.ToReturnType(attribute);
                var getter       = DoResolvePropertyGetter(propertyName, true);
                var indexType    = returnType.GetIndexType();
                var isIndexed    = indexType != null;
                var desc         = new EventPropertyDescriptor(propertyName, returnType, indexType, false, false, isIndexed, false, false);
                var @explicit    = new ExplicitPropertyDescriptor(desc, getter, false, null);
                additionalSchemaProps.Add(@explicit);
            }

            // Finally add XPath properties as that may depend on the rootElementNamespace
            Initialize(config.XPathProperties.Values, additionalSchemaProps);
        }
예제 #9
0
        private EventPropertyGetter DoResolvePropertyGetter(String propertyExpression, bool allowSimpleProperties)
        {
            EventPropertyGetter getter = _propertyGetterCache.Get(propertyExpression);

            if (getter != null)
            {
                return(getter);
            }

            if (!allowSimpleProperties)
            {
                // see if this is an indexed property
                int index = ASTUtil.UnescapedIndexOfDot(propertyExpression);
                if (index == -1)
                {
                    // parse, can be an indexed property
                    Property property = PropertyParser.ParseAndWalkLaxToSimple(propertyExpression);
                    if (!property.IsDynamic)
                    {
                        if (!(property is IndexedProperty))
                        {
                            return(null);
                        }
                        var indexedProp = (IndexedProperty)property;
                        getter = PropertyGetters.Get(indexedProp.PropertyNameAtomic);
                        if (null == getter)
                        {
                            return(null);
                        }
                        EventPropertyDescriptor descriptor = PropertyDescriptorMap.Get(indexedProp.PropertyNameAtomic);
                        if (descriptor == null)
                        {
                            return(null);
                        }
                        if (!descriptor.IsIndexed)
                        {
                            return(null);
                        }
                        if (descriptor.PropertyType == typeof(XmlNodeList))
                        {
                            FragmentFactory fragmentFactory = new FragmentFactoryDOMGetter(
                                EventAdapterService, this, indexedProp.PropertyNameAtomic);
                            return(new XPathPropertyArrayItemGetter(getter, indexedProp.Index, fragmentFactory));
                        }
                        if (descriptor.PropertyType == typeof(string))
                        {
                            FragmentFactory fragmentFactory = new FragmentFactoryDOMGetter(
                                EventAdapterService, this, indexedProp.PropertyNameAtomic);
                            return(new XPathPropertyArrayItemGetter(getter, indexedProp.Index, fragmentFactory));
                        }
                    }
                }
            }

            if (!_isPropertyExpressionXPath)
            {
                Property prop      = PropertyParser.ParseAndWalkLaxToSimple(propertyExpression);
                bool     isDynamic = prop.IsDynamic;

                if (!isDynamic)
                {
                    SchemaItem item = prop.GetPropertyTypeSchema(_schemaModelRoot, EventAdapterService);
                    if (item == null)
                    {
                        return(null);
                    }

                    getter = prop.GetGetterDOM(_schemaModelRoot, EventAdapterService, this, propertyExpression);
                    if (getter == null)
                    {
                        return(null);
                    }

                    Type returnType = SchemaUtil.ToReturnType(item);
                    if ((returnType != typeof(XmlNode)) && (returnType != typeof(XmlNodeList)))
                    {
                        if (!returnType.IsArray)
                        {
                            getter = new DOMConvertingGetter(propertyExpression, (DOMPropertyGetter)getter, returnType);
                        }
                        else
                        {
                            getter = new DOMConvertingArrayGetter((DOMPropertyGetter)getter, returnType.GetElementType());
                        }
                    }
                }
                else
                {
                    return(prop.GetGetterDOM());
                }
            }
            else
            {
                bool allowFragments = !ConfigurationEventTypeXMLDOM.IsXPathPropertyExpr;
                getter = SchemaXMLPropertyParser.GetXPathResolution(
                    propertyExpression,
                    NamespaceContext,
                    RootElementName,
                    _rootElementNamespace,
                    _schemaModel,
                    EventAdapterService,
                    this,
                    allowFragments,
                    ConfigurationEventTypeXMLDOM.DefaultNamespace);
            }

            _propertyGetterCache.Put(propertyExpression, getter);
            return(getter);
        }
예제 #10
0
        public Object Get(EventBean eventBean)
        {
            var und = eventBean.Underlying;

            if (und == null)
            {
                throw new PropertyAccessException("Unexpected null underlying event encountered, expecting System.Xml.XmlNode instance as underlying");
            }

            XPathNavigator navigator;

            var xnode = und as XElement;

            if (xnode == null)
            {
                var node = und as XmlNode;
                if (node == null)
                {
                    throw new PropertyAccessException("Unexpected underlying event of type '" + und.GetType().FullName +
                                                      "' encountered, expecting System.Xml.XmlNode as underlying");
                }

                if (Log.IsDebugEnabled)
                {
                    Log.Debug(
                        "Running XPath '{0}' for property '{1}' against Node XML : {2}",
                        _expressionText,
                        _property,
                        SchemaUtil.Serialize((XmlNode)und));
                }

                navigator = node.CreateNavigator();
            }
            else
            {
                navigator = xnode.CreateNavigator();
            }

            try
            {
                var result = navigator.Evaluate(_expression);
                if (result == null)
                {
                    return(null);
                }

                // if there is no parser, return xpath expression type
                if (_optionalCastToType == null)
                {
                    var nodeIterator = result as XPathNodeIterator;
                    if (nodeIterator != null)
                    {
                        if (nodeIterator.Count == 0)
                        {
                            return(null);
                        }
                        if (nodeIterator.Count == 1)
                        {
                            nodeIterator.MoveNext();
                            switch (_resultType)
                            {
                            case XPathResultType.Any:
                                return(((System.Xml.IHasXmlNode)nodeIterator.Current).GetNode());

                            case XPathResultType.String:
                                return(nodeIterator.Current.TypedValue);

                            case XPathResultType.Boolean:
                                return(nodeIterator.Current.ValueAsBoolean);

                            case XPathResultType.Number:
                                return(nodeIterator.Current.ValueAsDouble);

                            default:
                                return(nodeIterator.Current.TypedValue);
                            }
                        }
                        else
                        {
                            return(new XPathIteratorNodeList(nodeIterator));
                        }
                    }

                    return(result);
                }

                if (_isCastToArray)
                {
                    return(CastToArray(result));
                }

                if (result is XPathNodeIterator)
                {
                    var nodeIterator = result as XPathNodeIterator;
                    if (nodeIterator.Count == 0)
                    {
                        return(null);
                    }
                    if (nodeIterator.Count == 1)
                    {
                        nodeIterator.MoveNext();
                        result = nodeIterator.Current.TypedValue;
                    }
                    else
                    {
                        if (_simpleTypeParser == null)
                        {
                            var resultList = new List <object>();
                            while (nodeIterator.MoveNext())
                            {
                                result = nodeIterator.Current.TypedValue;
                                resultList.Add(result);
                            }

                            return(resultList.ToArray());
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }
                }

                // string results get parsed
                if (result is String)
                {
                    try
                    {
                        return(_simpleTypeParser.Invoke((string)result));
                    }
                    catch
                    {
                        Log.Warn("Error parsing XPath property named '" + _property + "' expression result '" + result + " as type " + _optionalCastToType.Name);
                        return(null);
                    }
                }

                // coercion
                if (result is Double)
                {
                    try
                    {
                        return(CoercerFactory.CoerceBoxed(result, _optionalCastToType));
                    }
                    catch
                    {
                        Log.Warn("Error coercing XPath property named '" + _property + "' expression result '" + result + " as type " + _optionalCastToType.Name);
                        return(null);
                    }
                }

                // check bool type
                if (result is Boolean)
                {
                    if (_optionalCastToType != typeof(bool?))
                    {
                        Log.Warn("Error coercing XPath property named '" + _property + "' expression result '" + result + " as type " + _optionalCastToType.Name);
                        return(null);
                    }
                    return(result);
                }

                Log.Warn("Error processing XPath property named '" + _property + "' expression result '" + result + ", not a known type");
                return(null);
            }
            catch (XPathException e) {
                throw new PropertyAccessException("Error getting property " + _property, e);
            }
        }
예제 #11
0
        public Object GetFragment(EventBean eventBean)
        {
            if (_fragmentFactory == null)
            {
                return(null);
            }

            Object und = eventBean.Underlying;

            if (und == null)
            {
                throw new PropertyAccessException("Unexpected null underlying event encountered, expecting System.Xml.XmlNode instance as underlying");
            }

            var node = und as XmlNode;

            if (node == null)
            {
                throw new PropertyAccessException("Unexpected underlying event of type '" + und.GetType().FullName + "' encountered, expecting System.Xml.XmlNode as underlying");
            }

            try {
                if (Log.IsDebugEnabled)
                {
                    Log.Debug(
                        "Running XPath '{0}' for property '{1}' against Node XML : {2}",
                        _expressionText,
                        _property,
                        SchemaUtil.Serialize((XmlNode)und));
                }

                var navigator = node.CreateNavigator();
                var result    = navigator.Evaluate(_expression);
                if (result == null)
                {
                    return(null);
                }

                if (result is XPathNodeIterator)
                {
                    var nodeIterator = result as XPathNodeIterator;
                    if (nodeIterator.Count == 0)
                    {
                        return(null);
                    }
                    if (nodeIterator.Count == 1)
                    {
                        nodeIterator.MoveNext();
                        return(_fragmentFactory.GetEvent(((IHasXmlNode)nodeIterator.Current).GetNode()));
                    }

                    var events = new List <EventBean>();
                    while (nodeIterator.MoveNext())
                    {
                        events.Add(_fragmentFactory.GetEvent(((IHasXmlNode)nodeIterator.Current).GetNode()));
                    }

                    return(events.ToArray());
                }

                Log.Warn("Error processing XPath property named '" + _property + "' expression result is not of type Node or Nodeset");
                return(null);
            }
            catch (XPathException e)
            {
                throw new PropertyAccessException("Error getting property " + _property, e);
            }
        }