Exemplo n.º 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))
            {
                var type = SchemaUtil.SimpleTypeToResultType(attribute.SimpleType);
                var 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");
        }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
0
        private Type DoResolvePropertyType(
            string propertyExpression,
            bool allowSimpleProperties)
        {
            // see if this is an indexed property
            var index = StringValue.UnescapedIndexOfDot(propertyExpression);
            if (!allowSimpleProperties && 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;
                    var descriptor = PropertyDescriptorMap.Get(indexedProp.PropertyNameAtomic);

                    return descriptor?.PropertyType;
                }
            }

            var prop = PropertyParser.ParseAndWalkLaxToSimple(propertyExpression);
            if (prop.IsDynamic) {
                return typeof(XmlNode);
            }

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

            return SchemaUtil.ToReturnType(item);
        }
Exemplo n.º 4
0
        public object Get(EventBean eventBean)
        {
            var und = eventBean.Underlying;
            if (und == null) {
                throw new PropertyAccessException(
                    "Unexpected null underlying event encountered, expecting org.w3c.dom.XmlNode instance as underlying");
            }

            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));
                }

                return GetFromUnderlying(node.CreateNavigator());
            }

            return GetFromUnderlying(xnode.CreateNavigator());
        }
Exemplo n.º 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="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));
        }
Exemplo n.º 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");
                }

                var 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");
            }

            var index         = GetIndexedPropertyIndex(property);
            var xPathPosition = index + 1;

            return(new Pair <string, XPathResultType>(
                       '/' + prefix + property.PropertyNameAtomic + "[position() = " + xPathPosition + ']',
                       type));
        }
Exemplo n.º 7
0
        public SchemaXMLEventType(
            EventTypeMetadata eventTypeMetadata,
            ConfigurationCommonEventTypeXMLDOM config,
            SchemaModel schemaModel,
            string representsFragmentOfProperty,
            string representsOriginalTypeName,
            EventBeanTypedEventFactory eventBeanTypedEventFactory,
            EventTypeNameResolver eventTypeResolver,
            XMLFragmentEventTypeFactory xmlEventTypeFactory)
            : base(
                eventTypeMetadata,
                config,
                eventBeanTypedEventFactory,
                eventTypeResolver,
                xmlEventTypeFactory)
        {
            propertyGetterCache = new Dictionary<string, EventPropertyGetterSPI>();
            SchemaModel = schemaModel;
            rootElementNamespace = config.RootElementNamespace;
            schemaModelRoot = SchemaUtil.FindRootElement(schemaModel, rootElementNamespace, RootElementName);
            isPropertyExpressionXPath = config.IsXPathPropertyExpr;
            RepresentsFragmentOfProperty = representsFragmentOfProperty;
            RepresentsOriginalTypeName = representsOriginalTypeName;

            // 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
            IList<ExplicitPropertyDescriptor> 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 (returnType == typeof(string)) {
                        propertyComponentType = typeof(char);
                    }
                }

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

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

                var getter = DoResolvePropertyGetter(propertyName, true);
                var desc = new EventPropertyDescriptor(
                    propertyName,
                    returnType,
                    propertyComponentType,
                    false,
                    false,
                    complex.IsArray,
                    false,
                    isFragment);
                var @explicit = new ExplicitPropertyDescriptor(desc, getter, false, null);
                additionalSchemaProps.Add(@explicit);
            }

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

            // Add a property for each attribute
            foreach (var attribute in schemaModelRoot.Attributes) {
                var propertyName = attribute.Name;
                var returnType = SchemaUtil.ToReturnType(attribute);
                var componentType = GenericExtensions.GetComponentType(returnType);
                var isIndexed = componentType != null;
                var getter = DoResolvePropertyGetter(propertyName, true);
                var desc = new EventPropertyDescriptor(
                    propertyName,
                    returnType,
                    componentType,
                    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);
        }
Exemplo n.º 8
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;
        }