Пример #1
0
 /// <summary>
 ///     Ctor.
 /// </summary>
 /// <param name="propertyName">property name</param>
 /// <param name="index">index</param>
 /// <param name="fragmentFactory">for creating fragments if required</param>
 public DOMIndexedGetter(
     string propertyName,
     int index,
     FragmentFactoryDOMGetter fragmentFactory)
 {
     this.propertyName = propertyName;
     this.index = index;
     this.fragmentFactory = fragmentFactory;
 }
Пример #2
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="eventBeanTypedEventFactory">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 EventPropertyGetterSPI GetXPathResolution(
            string propertyName,
            XPathNamespaceContext xPathContext,
            string rootElementName,
            string @namespace,
            SchemaModel schemaModel,
            EventBeanTypedEventFactory eventBeanTypedEventFactory,
            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 (var i = 0; i < namespaces.Count; i++)
            {
                var namespacePrefix = "n" + i;
                ctx.AddNamespace(namespacePrefix, namespaces[i]);
                if (defaultNamespace != null && defaultNamespace == namespaces[i])
                {
                    defaultNamespacePrefix = namespacePrefix;
                }
            }

            var property  = PropertyParser.ParseAndWalkLaxToSimple(propertyName);
            var isDynamic = property.IsDynamic;

            var rootComplexElement = SchemaUtil.FindRootElement(schemaModel, @namespace, rootElementName);
            var 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
            {
                var nestedProperty = (NestedProperty)property;
                var indexLast      = nestedProperty.Properties.Count - 1;

                for (var 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.IsDebugEnabled && 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) {
                var 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);

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

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

            FragmentFactory fragmentFactory = null;

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

            return(new XPathPropertyGetter(
                       xmlEventType,
                       propertyName,
                       xPath,
                       expr,
                       pair.Second,
                       resultType,
                       fragmentFactory));
        }
Пример #3
0
        private EventPropertyGetterSPI DoResolvePropertyGetter(
            string propertyExpression,
            bool allowSimpleProperties)
        {
            var getter = propertyGetterCache.Get(propertyExpression);
            if (getter != null) {
                return getter;
            }

            if (!allowSimpleProperties) {
                // see if this is an indexed property
                var index = StringValue.UnescapedIndexOfDot(propertyExpression);
                if (index == -1) {
                    // parse, can be an indexed property
                    var 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;
                        }

                        var descriptor = PropertyDescriptorMap.Get(indexedProp.PropertyNameAtomic);
                        if (descriptor == null) {
                            return null;
                        }

                        if (!descriptor.IsIndexed) {
                            return null;
                        }

                        if (descriptor.PropertyType == typeof(XmlNodeList)) {
                            FragmentFactorySPI fragmentFactory = new FragmentFactoryDOMGetter(
                                EventBeanTypedEventFactory,
                                this,
                                indexedProp.PropertyNameAtomic);
                            return new XPathPropertyArrayItemGetter(getter, indexedProp.Index, fragmentFactory);
                        } else if (descriptor.PropertyType == typeof(string)) {
                            FragmentFactorySPI fragmentFactory = new FragmentFactoryDOMGetter(
                                EventBeanTypedEventFactory,
                                this,
                                indexedProp.PropertyNameAtomic);
                            return new XPathPropertyArrayItemGetter(getter, indexedProp.Index, fragmentFactory);
                        }
                    }
                }
            }

            if (!isPropertyExpressionXPath) {
                var prop = PropertyParser.ParseAndWalkLaxToSimple(propertyExpression);
                var isDynamic = prop.IsDynamic;

                if (!isDynamic) {
                    var item = prop.GetPropertyTypeSchema(schemaModelRoot);
                    if (item == null) {
                        return null;
                    }

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

                    var returnType = SchemaUtil.ToReturnType(item);
                    if (returnType != typeof(XmlNode) && returnType != typeof(XmlNodeList)) {
                        if (!returnType.IsArray) {
                            getter = new DOMConvertingGetter((DOMPropertyGetter) getter, returnType);
                        }
                        else {
                            getter = new DOMConvertingArrayGetter(
                                (DOMPropertyGetter) getter,
                                returnType.GetElementType());
                        }
                    }
                }
                else {
                    return prop.GetterDOM;
                }
            }
            else {
                var allowFragments = !ConfigurationEventTypeXMLDOM.IsXPathPropertyExpr;
                getter = SchemaXMLPropertyParser.GetXPathResolution(
                    propertyExpression,
                    NamespaceContext,
                    RootElementName,
                    rootElementNamespace,
                    SchemaModel,
                    EventBeanTypedEventFactory,
                    this,
                    allowFragments,
                    ConfigurationEventTypeXMLDOM.DefaultNamespace);
            }

            propertyGetterCache.Put(propertyExpression, getter);
            return getter;
        }