/// <summary>
        /// Tries to create property functions.
        /// </summary>
        /// <param name="info">Function information.</param>
        /// <param name="function">Property Function.</param>
        /// <returns></returns>
        public bool TryCreatePropertyFunction(PropertyFunctionInfo info, out IPropertyFunctionPattern function)
        {
            function = null;
            switch (info.FunctionUri.AbsoluteUri)
            {
            case FullTextHelper.FullTextMatchPredicateUri:
                function = new PropertyFunctionPattern(info, new FullTextMatchPropertyFunction(info));
                return(true);

            default:
                return(false);
            }
        }
 /// <summary>
 /// Tries to create a property function
 /// </summary>
 /// <param name="info">Property Function information</param>
 /// <param name="localFactories">Locally Scoped factories</param>
 /// <param name="function">Property Function</param>
 /// <returns></returns>
 public static bool TryCreatePropertyFunction(PropertyFunctionInfo info, IEnumerable <IPropertyFunctionFactory> localFactories, out IPropertyFunctionPattern function)
 {
     function = null;
     // First try locally scoped factories
     foreach (IPropertyFunctionFactory factory in localFactories)
     {
         if (factory.TryCreatePropertyFunction(info, out function))
         {
             return(true);
         }
     }
     // Then try global factories
     foreach (IPropertyFunctionFactory factory in _factories)
     {
         if (factory.TryCreatePropertyFunction(info, out function))
         {
             return(true);
         }
     }
     return(false);
 }
Exemple #3
0
        /// <summary>
        /// Used to extract the patterns that make up property functions.
        /// </summary>
        /// <param name="patterns">Triple Patterns.</param>
        /// <param name="localFactories">Locally scoped factories.</param>
        /// <returns></returns>
        public static List <IPropertyFunctionPattern> ExtractPatterns(IEnumerable <ITriplePattern> patterns, IEnumerable <IPropertyFunctionFactory> localFactories)
        {
            // Do a first pass which simply looks to find any 'magic' properties
            Dictionary <PatternItem, PropertyFunctionInfo> funcInfo = new Dictionary <PatternItem, PropertyFunctionInfo>();
            List <IMatchTriplePattern> ps = patterns.OfType <IMatchTriplePattern>().ToList();

            if (ps.Count == 0)
            {
                return(new List <IPropertyFunctionPattern>());
            }
            foreach (IMatchTriplePattern tp in ps)
            {
                NodeMatchPattern predItem = tp.Predicate as NodeMatchPattern;
                if (predItem == null)
                {
                    continue;
                }
                IUriNode predNode = predItem.Node as IUriNode;
                if (predNode == null)
                {
                    continue;
                }
                if (PropertyFunctionFactory.IsPropertyFunction(predNode.Uri, localFactories))
                {
                    PropertyFunctionInfo info = new PropertyFunctionInfo(predNode.Uri);
                    info.Patterns.Add(tp);
                    funcInfo.Add(tp.Subject, info);
                }
            }
            // Remove any Patterns we found from the original patterns
            foreach (PropertyFunctionInfo info in funcInfo.Values)
            {
                info.Patterns.ForEach(tp => ps.Remove(tp));
            }

            if (funcInfo.Count == 0)
            {
                return(new List <IPropertyFunctionPattern>());
            }

            // Now for each 'magic' property we found do a further search to see if we are using
            // the collection forms to provide extended arguments
            foreach (PatternItem key in funcInfo.Keys)
            {
                if (key.VariableName != null && key.VariableName.StartsWith("_:"))
                {
                    // If LHS is a blank node may be collection form
                    int count = funcInfo[key].Patterns.Count;
                    ExtractRelatedPatterns(key, key, ps, funcInfo, funcInfo[key].SubjectArgs);
                    if (funcInfo[key].Patterns.Count == count)
                    {
                        // If no further patterns found just single LHS argument
                        funcInfo[key].SubjectArgs.Add(key);
                    }
                }
                else
                {
                    // Otherwise key is the only LHS argument
                    funcInfo[key].SubjectArgs.Add(key);
                }
                PatternItem searchKey = funcInfo[key].Patterns.First().Object;
                if (searchKey.VariableName != null && searchKey.VariableName.StartsWith("_:"))
                {
                    // If RHS is a blank node may be collection form
                    int count = funcInfo[key].Patterns.Count;
                    ExtractRelatedPatterns(key, searchKey, ps, funcInfo, funcInfo[key].ObjectArgs);
                    if (funcInfo[key].Patterns.Count == count)
                    {
                        // If no further patterns found just single RHS argument
                        funcInfo[key].ObjectArgs.Add(searchKey);
                    }
                }
                else
                {
                    // Otherwise single RHS argument
                    funcInfo[key].ObjectArgs.Add(searchKey);
                }
            }

            // Now try to create actual property functions
            List <IPropertyFunctionPattern> propFunctions = new List <IPropertyFunctionPattern>();

            foreach (PatternItem key in funcInfo.Keys)
            {
                IPropertyFunctionPattern propFunc;
                if (PropertyFunctionFactory.TryCreatePropertyFunction(funcInfo[key], localFactories, out propFunc))
                {
                    propFunctions.Add(propFunc);
                }
            }
            return(propFunctions);
        }
        /// <summary>
        /// Constructs a Full Text Match property function
        /// </summary>
        /// <param name="info">Property Function information</param>
        public FullTextMatchPropertyFunction(PropertyFunctionInfo info)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }
            if (!EqualityHelper.AreUrisEqual(info.FunctionUri, this.FunctionUri))
            {
                throw new ArgumentException("Property Function information is not valid for this function");
            }

            //Get basic arguments
            this._matchVar = info.SubjectArgs[0];
            if (this._matchVar.VariableName != null)
            {
                this._vars.Add(this._matchVar.VariableName);
            }
            if (info.SubjectArgs.Count == 2)
            {
                this._scoreVar = info.SubjectArgs[1];
                if (this._scoreVar.VariableName != null)
                {
                    this._vars.Add(this._scoreVar.VariableName);
                }
            }

            //Check extended arguments
            this._searchVar = info.ObjectArgs[0];
            if (this._searchVar.VariableName != null)
            {
                this._vars.Add(this._searchVar.VariableName);
            }
            switch (info.ObjectArgs.Count)
            {
            case 1:
                break;

            case 2:
                PatternItem arg = info.ObjectArgs[1];
                if (arg.VariableName != null)
                {
                    throw new RdfQueryException("Cannot use a variable as the limit/score threshold for full text queries, must use a numeric constant");
                }
                IValuedNode n = ((NodeMatchPattern)arg).Node.AsValuedNode();
                switch (n.NumericType)
                {
                case SparqlNumericType.Integer:
                    this._limit = (int)n.AsInteger();
                    break;

                case SparqlNumericType.Decimal:
                case SparqlNumericType.Double:
                case SparqlNumericType.Float:
                    this._threshold = n.AsDouble();
                    break;

                default:
                    throw new RdfQueryException("Cannot use a non-numeric constant as the limit/score threshold for full text queries, must use a numeric constant");
                }
                break;

            case 3:
            default:
                PatternItem arg1 = info.ObjectArgs[1];
                PatternItem arg2 = info.ObjectArgs[2];
                if (arg1.VariableName != null || arg2.VariableName != null)
                {
                    throw new RdfQueryException("Cannot use a variable as the limit/score threshold for full text queries, must use a numeric constant");
                }
                IValuedNode n1 = ((NodeMatchPattern)arg1).Node.AsValuedNode();
                switch (n1.NumericType)
                {
                case SparqlNumericType.NaN:
                    throw new RdfQueryException("Cannot use a non-numeric constant as the score threshold for full text queries, must use a numeric constant");

                default:
                    this._threshold = n1.AsDouble();
                    break;
                }
                IValuedNode n2 = ((NodeMatchPattern)arg2).Node.AsValuedNode();
                switch (n2.NumericType)
                {
                case SparqlNumericType.NaN:
                    throw new RdfQueryException("Cannot use a non-numeric constant as the limit for full text queries, must use a numeric constant");

                default:
                    this._limit = (int)n2.AsInteger();
                    break;
                }
                break;
            }
        }
 /// <summary>
 /// Tries to create a property function
 /// </summary>
 /// <param name="info">Property Function information</param>
 /// <param name="function">Property Function</param>
 /// <returns></returns>
 public static bool TryCreatePropertyFunction(PropertyFunctionInfo info, out IPropertyFunctionPattern function)
 {
     return(TryCreatePropertyFunction(info, Enumerable.Empty <IPropertyFunctionFactory>(), out function));
 }