/// <summary> /// Constructor for a Basic Graph Pattern Map /// </summary> /// <param name="queryModel">the graph pattern</param> /// <param name="offset">number of initial soluions to skip</param> /// <param name="limit">maximum number of solutions to take</param> /// <param name="filter">a bgp map filter</param> public BgpMap(LabelledTreeNode <object, Term> queryModel, int?offset = null, int?limit = null, IFilter filter = null) { _queryModel = queryModel; _offset = offset; _limit = limit; _filter = filter; }
/// <summary> /// Recursively create a query model for a particular type /// </summary> private LabelledTreeNode <object, Term> ConvertTypeToGraph(Type objectType) { var graph = new LabelledTreeNode <object, Term>(new Variable()); var resourceAttribute = objectType.GetTypeInfo().GetCustomAttribute <EntityBindAttribute>(); if (resourceAttribute != null) { graph.AddChild(new Rdf("type"), resourceAttribute.Type); } foreach (var member in objectType.GetRuntimeProperties()) { var memberAttribute = member.GetCustomAttribute <PropertyBindAttribute>(); if (memberAttribute != null) { Type relevantType; if (member.PropertyType.IsListType()) { relevantType = member.PropertyType.GenericTypeArguments[0]; } else { relevantType = member.PropertyType; } var memberGraph = ConvertTypeToGraph(relevantType); graph.AddChild(memberAttribute.Property, memberGraph); } } return(graph); }
/// <summary> /// Adds a graph portion to the repository /// </summary> public void Insert(LabelledTreeNode <object, Term> graph) { var body = SparqlBgpWriter.ConvertQueryModelToSparql(graph); var query = $"INSERT DATA {{{body}}}"; Client.ExecuteQuery(query, DefaultSource.EndPoint); }
/// <summary> /// Converts a tree query model into a sparql basic graph pattern /// </summary> public static string ConvertQueryModelToSparql(LabelledTreeNode <object, Term> queryModel) { string result = ""; foreach (var child in queryModel.Children) { result += string.Format(" {0} {1} {2}.", queryModel.Value, child.Edge, child.TerminalNode.Value) + ConvertQueryModelToSparql(child.TerminalNode); } return(result); }
/// <summary> /// Converts a tree query model into a sparql query string /// </summary> public static string Write(LabelledTreeNode <object, Term> queryModel, int?offset = null, int?limit = null, IFilter filter = null) { var template = "SELECT * WHERE {{ {0} {1}}} {2} {3}"; var whereBody = ConvertQueryModelToSparql(queryModel); var limitBody = limit.HasValue ? "LIMIT " + limit.Value : ""; var offsetBody = offset.HasValue ? "OFFSET " + offset.Value : ""; var filterBody = filter != null ? "FILTER " + filter.ToString() : ""; return(string.Format(template, whereBody, filterBody, limitBody, offsetBody)); }
/// <summary> /// Evaluates a graph query model against a graph source /// </summary> /// <param name="queryModel">tree model of the query</param> /// <param name="offset">number of solutions to skip</param> /// <param name="limit">maximum number of solutions to take</param> /// <param name="filter">a bgp filter</param> /// <param name="source">query target</param> /// <returns>A collection of trees</returns> public IEnumerable <LabelledTreeNode <object, Term> > Evaluate(LabelledTreeNode <object, Term> queryModel, int?offset, int?limit, IFilter filter, IGraphSource source) { var queryString = SparqlBgpWriter.Write(queryModel, offset, limit, filter); var client = new SparqlJsonClient(); var responseModel = client.ExecuteQuery(queryString, source.EndPoint); foreach (var solution in responseModel.Results.Bindings) { yield return(CreateResultGraph(solution, queryModel)); } }
/// <summary> /// Check the compatibility of two trees /// </summary> /// <param name="tree1">first tree</param> /// <param name="tree2">second tree</param> /// <param name="addressPairList">sites to compare</param> /// <returns>true if the trees are compatible</returns> public static bool Compatible(LabelledTreeNode <object, Term> tree1, LabelledTreeNode <object, Term> tree2, List <JoinAddressPair> addressPairList) { foreach (var x in addressPairList) { if (!tree1.Find(x.TreeAddress1).Value.Equals(tree2.Find(x.TreeAddress2).Value)) { return(false); } } return(true); }
/// <summary> /// Reflection based recursive method to populate a type with graph node values /// </summary> private object ConvertGraphToTypedObject(LabelledTreeNode <object, Term> objectGraph, Type type) { if (objectGraph.Children.Count == 0) { if (type.GetTypeInfo().IsAssignableFrom(objectGraph.Value.GetType())) { return(objectGraph.Value); } else { throw new InvalidCastException(string.Format("Cannot cast a {0} to a {1}", objectGraph.Value.GetType(), type)); } } //here we use the fact that expansion types inherit from Resource var obj = Activator.CreateInstance(type, new[] { objectGraph.Value }); foreach (var member in type.GetRuntimeProperties()) { var memberAttribute = member.GetCustomAttribute <PropertyBindAttribute>(); if (memberAttribute != null) { var memberObjectGraphCollection = objectGraph.Descend(memberAttribute.Property); if (member.PropertyType.IsListType()) { var typedList = Activator.CreateInstance(member.PropertyType); var addMethod = member.PropertyType.GetRuntimeMethod("Add", new Type[] { member.PropertyType.GenericTypeArguments[0] }); foreach (var memberObjectGraph in memberObjectGraphCollection) { addMethod.Invoke(typedList, new[] { ConvertGraphToTypedObject(memberObjectGraph, member.PropertyType.GenericTypeArguments[0]) }); } member.SetValue(obj, typedList); } else { LabelledTreeNode <object, Term> memberObjectGraph = null; try { memberObjectGraph = memberObjectGraphCollection.Single(); } catch (Exception) { throw new InvalidOperationException(string.Format("The type {0} declared a non collecton property {1} but more than one node matched", type, memberAttribute.Property)); } member.SetValue(obj, ConvertGraphToTypedObject(memberObjectGraph, member.PropertyType)); } } } return(obj); }
private void AddChildToGraph(LabelledTreeNode <object, Term> graph, object obj, Type objType, Resource property) { if (typeof(Resource).GetTypeInfo().IsAssignableFrom(objType)) { var memberGraph = CreateObjectGraph((Resource)obj); graph.AddChild(property, memberGraph); } else { var value = obj; graph.AddChild(property, value); } }
// Helper method to compute expression joins private JoinedMapResult CreateJoinedMap(Resource property, Term @object) { @object = @object ?? new Variable(); var joinSegment = new LabelledTreeNode <object, Term>(Root).AddChild(property, @object); IMap joinedMap = new BgpMap(joinSegment); var comparisonSites = new List <JoinAddressPair> { JoinAddressPair.RootComparison }; return(new JoinedMapResult { Map = joinedMap, AddressPairList = comparisonSites }); }
/// <summary> /// Join two trees /// </summary> /// <param name="treeBase">base tree</param> /// <param name="treeJoin">tree to join</param> /// <param name="addressPairList">sites of join</param> /// <returns>a combined tree</returns> public static LabelledTreeNode <object, Term> Join(LabelledTreeNode <object, Term> treeBase, LabelledTreeNode <object, Term> treeJoin, List <JoinAddressPair> addressPairList) { var localTreeBase = treeBase.Copy(); var localTreeJoin = treeJoin.Copy(); foreach (var x in addressPairList) { foreach (var child in localTreeJoin.Find(x.TreeAddress2).Children) { localTreeBase.Find(x.TreeAddress1).Children.Add(new DirectedEdge <Term, object>(child.Edge, child.TerminalNode)); } } return(localTreeBase); }
/// <summary> /// Create a graph of typed objects using the type graph as a model /// </summary> private LabelledTreeNode <object, Term> TypifyGraph(LabelledTreeNode <object, Term> objectGraph, LabelledTreeNode <Type, Term> typeGraph) { var obj = ConvertGraphToTypedObject(objectGraph, typeGraph.Value); var typedGraph = new LabelledTreeNode <object, Term>(obj); foreach (var outEdge in typeGraph.Children) { var edge = outEdge.Edge; var childTypeGraph = outEdge.TerminalNode; var childObjectGraphs = objectGraph.Descend(edge); foreach (var childObjectGraph in childObjectGraphs) { typedGraph.AddChild(edge, TypifyGraph(childObjectGraph, childTypeGraph)); } } return(typedGraph); }
public void InsertionAndDeletion() { IGraphContext context = new GraphContext(); var query = context.Select <RdfPropertyWithRange>(); int i = 0; foreach (var item in query) { i++; } Assert.Equal(181, i); var prop = new RdfPropertyWithRange("http://example.org/exampleprop"); prop.Range = new RdfClass("http://example.org/exampleclass"); context.Add(prop); i = 0; foreach (var item in query) { i++; } Assert.Equal(183, i); var graph = new LabelledTreeNode <object, Term>(prop); graph.AddChild(new Rdfs("range"), new RdfClass("http://example.org/exampleclass")); context.Remove(graph); i = 0; foreach (var item in query) { i++; } Assert.Equal(181, i); }
// Helper method to compute expression joins private JoinedMapResult CreateJoinedMap(Resource property, GraphExpression expression) { var joinSegment = new LabelledTreeNode <object, Term>(Root).AddChild(property, expression.Root); var joineMapComparisonSites = new List <JoinAddressPair> { new JoinAddressPair { TreeAddress1 = new List <Term> { property }, TreeAddress2 = new List <Term>() } }; IMap joinedMap = new JoinMap(new BgpMap(joinSegment), expression.Map, joineMapComparisonSites); var comparisonSites = new List <JoinAddressPair> { JoinAddressPair.RootComparison }; return(new JoinedMapResult { Map = joinedMap, AddressPairList = comparisonSites }); }
/// <summary> /// Generate a bgp regex filter using the variable names in the object graph /// </summary> /// <param name="queryGraph">graph model of the query</param> /// <returns></returns> public IFilter Generate(LabelledTreeNode <object, Term> queryGraph) { var propertyInfo = typeof(T).GetPropertyInfo(_propertyLambda); if (propertyInfo.Name == "Id") { var variable = queryGraph.Value as Variable; return(variable != null ? new RegexFilter($"str({variable})", _regex) : null); } var attribute = propertyInfo.CustomAttributes.OfType <PropertyBindAttribute>().SingleOrDefault(); if (attribute != null) { var node = queryGraph.Descend(attribute.Property).Single(); var variable = node.Value as Variable; return(variable != null ? new RegexFilter(variable.ToString(), _regex) : null); } return(null); }
private LabelledTreeNode <object, Term> CreateObjectGraph(Resource resource) { var graph = new LabelledTreeNode <object, Term>(new Resource(resource.Id)); var objectType = resource.GetType(); var resourceAttribute = objectType.GetTypeInfo().GetCustomAttribute <EntityBindAttribute>(); if (resourceAttribute != null) { graph.AddChild(new Rdf("type"), resourceAttribute.Type); } foreach (var member in objectType.GetRuntimeProperties()) { var memberAttribute = member.GetCustomAttribute <PropertyBindAttribute>(); if (memberAttribute != null) { Type relevantType; if (member.PropertyType.IsListType()) { relevantType = member.PropertyType.GenericTypeArguments[0]; var countMember = member.PropertyType.GetRuntimeProperty("Count"); var removeMethod = member.PropertyType.GetRuntimeMethod("Remove", new Type[] { }); while ((int)countMember.GetValue(member.GetValue(resource)) > 0) { var obj = removeMethod.Invoke(member.GetValue(resource), new object[] { }); AddChildToGraph(graph, obj, relevantType, memberAttribute.Property); } } else { relevantType = member.PropertyType; var obj = member.GetValue(resource); AddChildToGraph(graph, obj, relevantType, memberAttribute.Property); } } } return(graph); }
/// <summary> /// Returns an instance of a constant map which will return its value whenever executed /// </summary> /// <param name="value"></param> public ConstantMap(LabelledTreeNode <object, Term> value) { _value = new[] { value }; }
/// <summary> /// Public constructor with query model initializer /// </summary> public GraphExpression(LabelledTreeNode <object, Term> queryModel, IFilter filter = null) { Root = (Term)queryModel.Value; Map = new BgpMap(queryModel, filter: filter); }
//Converts a JSON sparql solution binding row into a graph result private LabelledTreeNode <object, Term> CreateResultGraph(Dictionary <string, Binding> solution, LabelledTreeNode <object, Term> queryModel) { TreeNodeVisitor <object, object> visitor = (object nodeData) => ResolveNode(nodeData, solution); var result = queryModel.Copy().Traverse(visitor); return(result); }
public IEnumerable <LabelledTreeNode <object, Term> > Evaluate(LabelledTreeNode <object, Term> queryModel, int?offset, int?limit, IFilter filter, IGraphSource source) { if (source.EndPoint.Equals(TestUris.MathematiciansRepoUri)) //8 mathematicians { var archimedes = new LabelledTreeNode <object, Term>("archimedes"); var gauss = new LabelledTreeNode <object, Term>("gauss"); var descartes = new LabelledTreeNode <object, Term>("descartes"); var euclid = new LabelledTreeNode <object, Term>("euclid"); var newton = new LabelledTreeNode <object, Term>("newton"); var pythagoras = new LabelledTreeNode <object, Term>("pythagoras"); var euler = new LabelledTreeNode <object, Term>("euler"); var leibniz = new LabelledTreeNode <object, Term>("leibniz"); archimedes.AddChild(Biografy.Name, "Archimedes") .AddChild(Biografy.YearOfBirth, -287) .AddChild(Biografy.YearOfDeath, -212) .AddChild(Biografy.Nationality, "greece"); gauss.AddChild(Biografy.Name, "Carl Friedrich Gauss") .AddChild(Biografy.YearOfBirth, 1777) .AddChild(Biografy.YearOfDeath, 1855) .AddChild(Biografy.Nationality, "germany"); descartes.AddChild(Biografy.Name, "René Descartes") .AddChild(Biografy.YearOfBirth, 1596) .AddChild(Biografy.YearOfDeath, 1650) .AddChild(Biografy.Nationality, "france"); euclid.AddChild(Biografy.Name, "Euclid") .AddChild(Biografy.YearOfBirth, -325) .AddChild(Biografy.YearOfDeath, -265) .AddChild(Biografy.Nationality, "greece"); newton.AddChild(Biografy.Name, "Isaac Newton") .AddChild(Biografy.YearOfBirth, 1643) .AddChild(Biografy.YearOfDeath, 1727) .AddChild(Biografy.Nationality, "england"); pythagoras.AddChild(Biografy.Name, "Pythagoras") .AddChild(Biografy.YearOfBirth, -569) .AddChild(Biografy.YearOfDeath, -475) .AddChild(Biografy.Nationality, "greece"); euler.AddChild(Biografy.Name, "Leonhard Euler") .AddChild(Biografy.YearOfBirth, 1707) .AddChild(Biografy.YearOfDeath, 1783) .AddChild(Biografy.Nationality, "switzerland"); leibniz.AddChild(Biografy.Name, "Gottfried Wilhelm Leibniz") .AddChild(Biografy.YearOfBirth, 1646) .AddChild(Biografy.YearOfDeath, 1716) .AddChild(Biografy.Nationality, "germany"); yield return(archimedes); yield return(gauss); yield return(descartes); yield return(euclid); yield return(newton); yield return(pythagoras); yield return(euler); yield return(leibniz); } else if (source.EndPoint.Equals(TestUris.PhysicistRepoUri)) //7 physiscists { var einstein = new LabelledTreeNode <object, Term>("einstein"); var curie = new LabelledTreeNode <object, Term>("curie"); var bohr = new LabelledTreeNode <object, Term>("bohr"); var feynman = new LabelledTreeNode <object, Term>("feynman"); var newton = new LabelledTreeNode <object, Term>("newton"); var galilei = new LabelledTreeNode <object, Term>("galilei"); var maxwell = new LabelledTreeNode <object, Term>("maxwell"); einstein.AddChild(Biografy.Name, "Albert Einstein") .AddChild(Biografy.YearOfBirth, 1879) .AddChild(Biografy.YearOfDeath, 1955) .AddChild(Biografy.Nationality, "germany"); curie.AddChild(Biografy.Name, "Marie Curie") .AddChild(Biografy.YearOfBirth, 1867) .AddChild(Biografy.YearOfDeath, 1934) .AddChild(Biografy.Nationality, "france"); bohr.AddChild(Biografy.Name, "Niels Bohr") .AddChild(Biografy.YearOfBirth, 1885) .AddChild(Biografy.YearOfDeath, 1962) .AddChild(Biografy.Nationality, "denmark"); feynman.AddChild(Biografy.Name, "Richard Feynman") .AddChild(Biografy.YearOfBirth, 1918) .AddChild(Biografy.YearOfDeath, 1988) .AddChild(Biografy.Nationality, "usa"); newton.AddChild(Biografy.Name, "Isaac Newton") .AddChild(Biografy.YearOfBirth, 1643) .AddChild(Biografy.YearOfDeath, 1727) .AddChild(Biografy.Nationality, "england"); galilei.AddChild(Biografy.Name, "Galileo Galilei") .AddChild(Biografy.YearOfBirth, 1564) .AddChild(Biografy.YearOfDeath, 1642) .AddChild(Biografy.Nationality, "italy"); maxwell.AddChild(Biografy.Name, "James Clerk Maxwell") .AddChild(Biografy.YearOfBirth, 1831) .AddChild(Biografy.YearOfDeath, 1879) .AddChild(Biografy.Nationality, "scottland"); yield return(einstein); yield return(curie); yield return(bohr); yield return(feynman); yield return(newton); yield return(galilei); yield return(maxwell); } else if (source.EndPoint.Equals(TestUris.NationsRepouri)) //7 nations { var germany = new LabelledTreeNode <object, Term>("germany"); var france = new LabelledTreeNode <object, Term>("france"); var denmark = new LabelledTreeNode <object, Term>("denmark"); var greece = new LabelledTreeNode <object, Term>("greece"); var italy = new LabelledTreeNode <object, Term>("italy"); var england = new LabelledTreeNode <object, Term>("england"); var scottland = new LabelledTreeNode <object, Term>("scottland"); var usa = new LabelledTreeNode <object, Term>("usa"); var switzerland = new LabelledTreeNode <object, Term>("switzerland"); germany.AddChild(Geografy.Name, "Germany") .AddChild(Geografy.Capital, "Berlin") .AddChild(Geografy.Continent, "Europe") .AddChild(Geografy.Population, 80620000); france.AddChild(Geografy.Name, "France") .AddChild(Geografy.Capital, "Paris") .AddChild(Geografy.Continent, "Europe") .AddChild(Geografy.Population, 66030000); denmark.AddChild(Geografy.Name, "Denmark") .AddChild(Geografy.Capital, "Berlin") .AddChild(Geografy.Continent, "Europe"); greece.AddChild(Geografy.Name, "Greece") .AddChild(Geografy.Capital, "Athens") .AddChild(Geografy.Continent, "Europe") .AddChild(Geografy.Population, 11030000); italy.AddChild(Geografy.Name, "Italy") .AddChild(Geografy.Capital, "Rome") .AddChild(Geografy.Continent, "Europe"); england.AddChild(Geografy.Name, "England") .AddChild(Geografy.Capital, "Berlin") .AddChild(Geografy.Continent, "Europe") .AddChild(Geografy.Population, 53010000); scottland.AddChild(Geografy.Name, "Scottland") .AddChild(Geografy.Capital, "Berlin") .AddChild(Geografy.Continent, "Europe") .AddChild(Geografy.Population, 5295000); usa.AddChild(Geografy.Name, "United States Of America") .AddChild(Geografy.Capital, "Washington") .AddChild(Geografy.Continent, "America") .AddChild(Geografy.Population, 318900000); switzerland.AddChild(Geografy.Name, "Switzerland") .AddChild(Geografy.Capital, "Bern") .AddChild(Geografy.Continent, "Europe") .AddChild(Geografy.Population, 8081000); yield return(germany); yield return(france); yield return(denmark); yield return(greece); yield return(england); yield return(scottland); yield return(usa); yield return(switzerland); } else { yield return(new LabelledTreeNode <object, Term>(null)); } }
/// <summary> /// Constructor /// </summary> /// <param name="edge"></param> /// <param name="node"></param> public DirectedEdge(TE edge, LabelledTreeNode <TN, TE> node) { Edge = edge; TerminalNode = node; }
/// <summary> /// Contructor /// </summary> /// <param name="edge"></param> /// <param name="nodeData"></param> public DirectedEdge(TE edge, TN nodeData) { Edge = edge; TerminalNode = new LabelledTreeNode <TN, TE>(nodeData); }
/// <summary> /// Removes a graph /// </summary> public void Remove(LabelledTreeNode <object, Term> graph) { GraphWriter.Delete(graph); }
/// <summary> /// Appends a graph /// </summary> public void Append(LabelledTreeNode <object, Term> graph) { GraphWriter.Insert(graph); }
/// <summary> /// Initializes a new instance of a QueryableGraph <T> class, for internal usage /// </summary> private TypedQueryableGraph(IGraphProvider graphProvider, GraphExpression graphExpression, LabelledTreeNode <Type, Term> typeGraph) : base(graphProvider, graphExpression) { TypeGraph = typeGraph; }