diff --git a/mkdocs/search_index.json b/mkdocs/search_index.json index b9b2039c4b2451176da0c5a29ab910aff3e36c61..1c344543d352a8729b67fced225770e4b4a6e643 100644 --- a/mkdocs/search_index.json +++ b/mkdocs/search_index.json @@ -77,12 +77,12 @@ }, { "location": "/object_mapping/", - "text": "Ferma is an Object-graph Model (OGM). An Object-graph Model is to a Graph Database as an Object-relational Model (ORM)\nis to a Relational Database. That is to say that it maps Java Objects to edges and vertex in a graph database. As a\nnatural consequence the Java types become an implied Schema for a Graph Database even if the underlying implementation\ndoesnt support the notion of a schema.\n\n\nThe objects associated with the various types of Edges and Vertex in a graph are collectively called the Graph Data\nModel (GDM). Each Java type in the GDM will usually represent a class of Edges or Vertex in underlying graph. All Edges\nin the model will extend from the \nEdgeFrame\n interface and all vertex will extend from \nVertexFrame\n interface. The\nindividual classes that comprise the GDM are usually simply refered to as Frames.\n\n\nThe methods defined by a Frame will represent interactions with the underlying graph via traversals that are relative, \nusing the current edge or vertex as their starting point.\n\n\npublic\n \ninterface\n \nPerson\n \nextends\n \nVertexFrame\n \n{\n\n \nString\n \ngetName\n();\n\n \nList\n?\n \nextends\n \nPerson\n \ngetCoworkers\n();\n\n\n}\n\n\n\n\n\nIn this example Person represents a vertex in the graph with a property indicating their name, and they are associated\nwith other vertex in the graph of the same type that represent their coworkers.\n\n\nWhen implementing a vertex as a concrete class you must instead inherit from \nAbstractVertexFrame\n.\n\n\npublic\n \nclass\n \nPerson\n \nextends\n \nAbstractVertexFrame\n \n{\n\n \npublic\n \nString\n \ngetName\n()\n \n{\n\n \nreturn\n \nthis\n.\ngetProperty\n(\nname\n);\n\n \n}\n\n\n \npublic\n \nList\n?\n \nextends\n \nPerson\n \ngetCoworkers\n()\n \n{\n\n \nreturn\n \nthis\n.\ntraverse\n(\nv\n \n-\n \nv\n.\nout\n(\ncoworker\n)).\ntoList\n(\nPerson\n.\nclass\n);\n\n \n}\n\n\n}\n\n\n\n\n\nIt is also possible to do the same with inheritance if you want a class and an interface defined.\n\n\npublic\n \nclass\n \nPersonImpl\n \nextends\n \nAbstractVertexFrame\n \nimplements\n \nPerson\n \n{\n\n \n@Override\n\n \npublic\n \nString\n \ngetName\n()\n \n{\n\n \nreturn\n \nthis\n.\ngetProperty\n(\nname\n);\n\n \n}\n\n\n \n@Override\n\n \npublic\n \nList\n?\n \nextends\n \nPerson\n \ngetCoworkers\n()\n \n{\n\n \nreturn\n \nthis\n.\ntraverse\n(\nv\n \n-\n \nv\n.\nout\n(\ncoworker\n)).\ntoList\n(\nPerson\n.\nclass\n);\n\n \n}\n\n\n}\n\n\n\n\n\n\n\nNote\n\n\nWhen implementing a Frame a class or abstract class must always extend from either \nAbstractEdgeFrame\n or\n\nAbstractVertexFrame\n.\n\n\n\n\nTyping\n\n\nThere are two typing modes for ferma and each significantly effects how the user will determine the type of the objects\npulled from the graph, these modes are called \nTyped Mode\n and \nUntyped Mode\n.\n\n\nWhen performing a traversal on a Frame there are several methods provided which automatically encapsulate the underlying\ngraph element or elements into a framed equivelant such as a \nVertexFrame\n or a \nEdgeFrame\n. This may either be a single\nFrame, \nIterator\n, \nSet\n, or \nList\n of Frames.\n\n\nIn the earlier example we used a traversal to find all the coworkers, we used the \ntoList()\n method to frame all the\nunderlying vertex into the \nPerson\n type.\n\n\nthis\n.\ntraverse\n(\nv\n \n-\n \nv\n.\nout\n(\ncoworker\n)).\ntoList\n(\nPerson\n.\nclass\n);\n\n\n\n\n\nTraversals have several different methods availible that each frame and collect the underlying elements in different\nways, those methods, members of the \nTraversable\n interface, are the following.\n\n\nN\n \nN\n \nnext\n(\nClass\nN\n \nkind\n);\n\n\nN\n \nList\n?\n \nextends\n \nN\n \nnext\n(\nint\n \namount\n,\n \nClass\nN\n \nkind\n);\n\n\nN\n \nN\n \nnextOrDefault\n(\nClass\nN\n \nkind\n,\n \nN\n \ndefaultValue\n);\n\n\nVertexFrame\n \nnextOrAdd\n();\n\n\nN\n \nN\n \nnextOrAdd\n(\nClassInitializer\nN\n \ninitializer\n);\n\n\nN\n \nN\n \nnextOrAdd\n(\nClass\nN\n \nkind\n);\n\n\nN\n \nIterator\nN\n \nframe\n(\nClass\nN\n \nkind\n);\n\n\nN\n \nList\n?\n \nextends\n \nN\n \ntoList\n(\nClass\nN\n \nkind\n);\n\n\nN\n \nSet\n?\n \nextends\n \nN\n \ntoSet\n(\nClass\nN\n \nkind\n);\n\n\n\n\n\n\n\nNote\n\n\nEach of these methods also have an equivelant method with the suffix \nExplicit\n, we will discuss those later as they\nonly become important when we begin to discuss the differences between Typed Mode and \nUntyped Mode\n.\n\n\n\n\nEach of these methods has a slightly different behavior. For full details see the Ferma Javadocs for the Traversable\nclass. However, in short, the \nnext(Class)\n method returns any one of the matching elements and frames it as the\nspecified type. It will throw an exception however if no vertex are found. The \nnextOrDefault\n varient avoids the\nexception by returning the default value when there are no matches, which can be \n0\n or \nnull\n for example. Similarly\n\nnextOrAdd\n will add a new vertex to the underlying graph if the traversal yields no matches. Finally \nframe(Class)\n,\n\ntoList(Class)\n, and \ntoSet(Class)\n will return all elements that match the traversal as either a \nIterator\n, \nList\n, \nor a \nSet\n.\n\n\nThe exact type returned from all the aforementioned calls will always be a Class of the type specified in the argument,\nor a subclass thereof. The exact type of the class instantiated will depend on which typing mode is being used.\n\n\nUntyped Mode\n\n\nIn untyped mode there is never any Java type information encoded into the underlying graph. This means when you take an\nobject off the graph there is no way for Ferma to know what Java type it is associated with and the user must select\nthe type manually. Since a Frame just defines a set of behaviors and properties exposed for a particular graph\nelement it can sometimes be useful to pick which Frame to use to represent an element based on how you need to interact\nwith that element rather than a one to one mapping of element to a specific type. In such a scenario Untyped Mode might\nbe the ideal choice.\n\n\nIn this mode when framing elements from a traversal the type of the element is determined entierly from the parameters\npassed to the methods invoked on the Traversable class. The following is an example of how to frame a vertex as a\n\nPerson\n class from above.\n\n\n// Open an untyped Framed Graph\n\n\nFramedGraph\n \nfg\n \n=\n \nnew\n \nDelegatingFramedGraph\n(\nTinkerGraph\n.\nopen\n());\n\n\n\n//create a vertex with no type information and a single name property\n\n\nVertexFrame\n \nvertex\n \n=\n \nfg\n.\naddFramedVertex\n(\nVertexFrame\n.\nclass\n);\n\n\nvertex\n.\nsetProperty\n(\nname\n,\n \nJeff\n);\n\n\n\n//retrieve the vertex we just created but this time frame it as a Person\n\n\nPerson\n \nperson\n \n=\n \nfg\n.\ntraverse\n(\ng\n \n-\n \ng\n.\nV\n().\nproperty\n(\nname\n,\n \njeff\n)).\nnextExplicit\n(\nPerson\n.\nclass\n);\n\n\nassert\n \nperson\n.\ngetName\n().\nequals\n(\nJeff\n);\n\n\n\n\n\n\n\nNote\n\n\nIn untyped mode all the \nTraversal\n methods with the suffix of \nExplicit\n behave exactly the same as those methods\nwithout the suffix. Therefore when working in untyped mode it is suggested you only use explicit methods. This way\nif you ever decide to migrate over to typed mode it will not change the behavior of your existing code base and will\nmake the migration process much easier. \n\n\n\n\nTyped Mode\n\n\nTyped mode takes things one step further and allows type information about a frame to be encoded as a\nproperty on vertex and edges in the underlying graph. This behavior is governed by the \nPolymorphicTypeResolver\n which\nencodes the type in a property name which defaults to the value of \nPolymorphicTypeResolver.TYPE_RESOLUTION_KEY\n but can\nbe explicitly set to any string value of the user's choice. When a class is framed the Type Resolution Key is read and\nthe original type is determined, this in turn effects the type used to instantiate the new Frame and may be a specific\ntype which is a subclass of the type requested. For example say we have the following model. \n\n\npublic\n \nclass\n \nPerson\n \nextends\n \nAbstractVertexFrame\n \n{\n\n \npublic\n \nString\n \ngetName\n()\n \n{\n\n \nreturn\n \nthis\n.\ngetProperty\n(\nname\n);\n\n \n}\n\n\n \npublic\n \nList\n?\n \nextends\n \nPerson\n \ngetFriends\n()\n \n{\n\n \nreturn\n \nthis\n.\ntraverse\n(\nv\n \n-\n \nv\n.\nout\n(\nfriend\n)).\ntoList\n(\nPerson\n.\nclass\n);\n\n \n}\n\n\n}\n\n\n\npublic\n \nclass\n \nProgrammer\n \nextends\n \nPerson\n \n{\n\n \n@Override\n\n \npublic\n \nList\n?\n \nextends\n \nProgrammer\n \ngetFriends\n()\n \n{\n\n \n//Programmers don\nt have friends :(\n\n \nreturn\n \nCollections\n.\nemptyList\n();\n\n \n}\n\n\n}\n\n\n\n\n\nIn this case we can encode a \nProgrammer\n vertex into the graph and even if we try to retrieve and frame that vertex as a\n\nVertexFrame\n or \nPerson\n in the future the instantiated type will still be \nProgrammer\n. This allows for a truly\npolymorphic Graph Data Model that leverages method overriding and class inheritance functiuonality in the model. For\nexample the following is possible now in Typed Mode.\n\n\n// Open a Framed Graph in Typed Mode\n\n\nFramedGraph\n \nfg\n \n=\n \nnew\n \nDelegatingFramedGraph\n(\nTinkerGraph\n.\nopen\n(),\n \ntrue\n,\n \nfalse\n);\n\n\n\n//create a vertex with type information specifying it as the Programmer type\n\n\nProgrammer\n \nprogrammer\n \n=\n \nfg\n.\naddFramedVertex\n(\nProgrammer\n.\nclass\n);\n\n\nprogrammer\n.\nsetName\n(\nJeff\n);\n\n\n\n//retrieve the vertex we just created and check it is instantiated as a Programer\n\n\nPerson\n \nperson\n \n=\n \nfg\n.\ntraverse\n(\ng\n \n-\n \ng\n.\nV\n().\nproperty\n(\nname\n,\n \njeff\n)).\nnext\n(\nPerson\n.\nclass\n);\n\n\nassert\n \nperson\n \ninstanceof\n \nProgrammer\n;\n\n\nassert\n \nperson\n.\ngetFriends\n().\nisEmpty\n();\n\n\n\n\n\nThe methods with the \nExplicit\n suffix are particularly meaningful for Typed Mode. In this mode they bypass the encoded\ntyping completely and instantiate the frame as if in Untyped Mode. The following code snippet provides an\nexample using the same model.\n\n\n// Open typed Framed Graph\n\n\nFramedGraph\n \nfg\n \n=\n \nnew\n \nDelegatingFramedGraph\n(\nTinkerGraph\n.\nopen\n(),\n \ntrue\n,\n \nfalse\n);\n\n\n\n//create a vertex with no type information and a single name property\n\n\nProgrammer\n \nprogrammer\n \n=\n \nfg\n.\naddFramedVertex\n(\nProgrammer\n.\nclass\n);\n\n\nprogrammer\n.\nsetName\n(\nJeff\n);\n\n\n\n//retrieve the vertex we just created, since we are using an excplicit method the type won\nt be Programmer this time.\n\n\nPerson\n \nperson\n \n=\n \nfg\n.\ntraverse\n(\ng\n \n-\n \ng\n.\nV\n().\nproperty\n(\nname\n,\n \njeff\n)).\nnextExplicit\n(\nPerson\n.\nclass\n);\n\n\nassert\n \n!(\nperson\n \ninstanceof\n \nProgrammer\n);\n\n\n\n\n\nThe following are the list of explicit method types in the Traversable class.\n\n\nN\n \nN\n \nnextExplicit\n(\nClass\nN\n \nkind\n);\n\n\nN\n \nList\n?\n \nextends\n \nN\n \nnextExplicit\n(\nint\n \namount\n,\n \nClass\nN\n \nkind\n);\n\n\nN\n \nN\n \nnextOrDefaultExplicit\n(\nClass\nN\n \nkind\n,\n \nN\n \ndefaultValue\n);\n\n\nN\n \nN\n \nnextOrAddExplicit\n(\nClassInitializer\nN\n \ninitializer\n);\n\n\nN\n \nN\n \nnextOrAddExplicit\n(\nClass\nN\n \nkind\n);\n\n\nN\n \nIterator\n?\n \nextends\n \nN\n \nframeExplicit\n(\nClass\nN\n \nkind\n);\n\n\nN\n \nList\n?\n \nextends\n \nN\n \ntoListExplicit\n(\nClass\nN\n \nkind\n);\n\n\nN\n \nSet\n?\n \nextends\n \nN\n \ntoSetExplicit\n(\nClass\nN\n \nkind\n);\n\n\n\n\n\nIt is also possible to change the type encoded in the underlying graph after the element has already been created. The\nfollowing example demonstrates this feature.\n\n\nFramedGraph\n \nfg\n \n=\n \nnew\n \nDelegatingFramedGraph\n(\nTinkerGraph\n.\nopen\n(),\n \ntrue\n,\n \nfalse\n);\n\n\n\n//create a vertex with type information specifying it as the Programmer type\n\n\nProgrammer\n \nprogrammer\n \n=\n \nfg\n.\naddFramedVertex\n(\nProgrammer\n.\nclass\n);\n\n\nprogrammer\n.\nsetName\n(\nJeff\n);\n\n\n\n//retrieve the vertex we just created and check it is instantiated as a Programer\n\n\nPerson\n \nperson\n \n=\n \nfg\n.\ntraverse\n(\ng\n \n-\n \ng\n.\nV\n().\nproperty\n(\nname\n,\n \njeff\n)).\nnext\n(\nPerson\n.\nclass\n);\n\n\nassert\n \nperson\n \ninstanceof\n \nProgrammer\n;\n\n\n\n//change the type resolution to person\n\n\nperson\n.\nsetTypeResolution\n(\nPerson\n.\nclass\n);\n\n\n\n//retrieve the vertex again to show the type changed\n\n\nperson\n \n=\n \nfg\n.\ntraverse\n(\ng\n \n-\n \ng\n.\nV\n().\nproperty\n(\nname\n,\n \njeff\n)).\nnext\n(\nPerson\n.\nclass\n);\n\n\nassert\n(!(\nperson\n \ninstanceof\n \nProgrammer\n));\n\n\nassert\n(\nperson\n \ninstanceof\n \nPerson\n);", + "text": "Ferma is an Object-graph Model (OGM). An Object-graph Model is to a Graph Database as an Object-relational Model (ORM)\nis to a Relational Database. That is to say that it maps Java Objects to edges and vertex in a graph database. As a\nnatural consequence the Java types become an implied Schema for a Graph Database even if the underlying implementation\ndoesnt support the notion of a schema.\n\n\nThe objects associated with the various types of Edges and Vertex in a graph are collectively called the Graph Data\nModel (GDM). Each Java type in the GDM will usually represent a class of Edges or Vertex in the underlying graph. All\nEdges in the model will extend from the \nEdgeFrame\n interface and all vertex will extend from the \nVertexFrame\n\ninterface. The individual classes that comprise the GDM are usually simply refered to as frames.\n\n\nThe methods defined by a frame will represent interactions with the underlying graph via traversals that are relative, \nusing the current edge or vertex as their starting point.\n\n\npublic\n \ninterface\n \nPerson\n \nextends\n \nVertexFrame\n \n{\n\n \nString\n \ngetName\n();\n\n \nList\n?\n \nextends\n \nPerson\n \ngetCoworkers\n();\n\n\n}\n\n\n\n\n\nIn this example Person represents a vertex in the graph with a property indicating their name, and they are associated\nwith other vertex in the graph of the same type that represent their coworkers.\n\n\nWhen implementing a vertex as a concrete class you must instead inherit from \nAbstractVertexFrame\n.\n\n\npublic\n \nclass\n \nPerson\n \nextends\n \nAbstractVertexFrame\n \n{\n\n \npublic\n \nString\n \ngetName\n()\n \n{\n\n \nreturn\n \nthis\n.\ngetProperty\n(\nname\n);\n\n \n}\n\n\n \npublic\n \nList\n?\n \nextends\n \nPerson\n \ngetCoworkers\n()\n \n{\n\n \nreturn\n \nthis\n.\ntraverse\n(\nv\n \n-\n \nv\n.\nout\n(\ncoworker\n)).\ntoList\n(\nPerson\n.\nclass\n);\n\n \n}\n\n\n}\n\n\n\n\n\nIt is also possible to do the same with inheritance if you want a class and an interface defined.\n\n\npublic\n \nclass\n \nPersonImpl\n \nextends\n \nAbstractVertexFrame\n \nimplements\n \nPerson\n \n{\n\n \n@Override\n\n \npublic\n \nString\n \ngetName\n()\n \n{\n\n \nreturn\n \nthis\n.\ngetProperty\n(\nname\n);\n\n \n}\n\n\n \n@Override\n\n \npublic\n \nList\n?\n \nextends\n \nPerson\n \ngetCoworkers\n()\n \n{\n\n \nreturn\n \nthis\n.\ntraverse\n(\nv\n \n-\n \nv\n.\nout\n(\ncoworker\n)).\ntoList\n(\nPerson\n.\nclass\n);\n\n \n}\n\n\n}\n\n\n\n\n\n\n\nNote\n\n\nWhen implementing a Frame a class or abstract class must always extend from either \nAbstractEdgeFrame\n or\n\nAbstractVertexFrame\n.\n\n\n\n\nTyping\n\n\nThere are two typing modes for ferma and each significantly effects how the user will determine the type of the objects\npulled from the graph, these modes are called \nTyped Mode\n and \nUntyped Mode\n.\n\n\nWhen performing a traversal on a frame there are several methods provided which automatically encapsulate the underlying\ngraph element or elements into a framed equivelant such as a \nVertexFrame\n or an \nEdgeFrame\n. This may be either a single\nframe, or a group of frames provided by an \nIterator\n, \nSet\n, or \nList\n.\n\n\nIn the earlier example we used a traversal to find all the coworkers and we used the \ntoList()\n method to frame all the\nunderlying vertex into the \nPerson\n type.\n\n\nthis\n.\ntraverse\n(\nv\n \n-\n \nv\n.\nout\n(\ncoworker\n)).\ntoList\n(\nPerson\n.\nclass\n);\n\n\n\n\n\nTraversals have several different methods availible that each frame and collect the underlying elements in different\nways, those methods, members of the \nTraversable\n interface, are the following.\n\n\nN\n \nN\n \nnext\n(\nClass\nN\n \nkind\n);\n\n\nN\n \nList\n?\n \nextends\n \nN\n \nnext\n(\nint\n \namount\n,\n \nClass\nN\n \nkind\n);\n\n\nN\n \nN\n \nnextOrDefault\n(\nClass\nN\n \nkind\n,\n \nN\n \ndefaultValue\n);\n\n\nVertexFrame\n \nnextOrAdd\n();\n\n\nN\n \nN\n \nnextOrAdd\n(\nClassInitializer\nN\n \ninitializer\n);\n\n\nN\n \nN\n \nnextOrAdd\n(\nClass\nN\n \nkind\n);\n\n\nN\n \nIterator\nN\n \nframe\n(\nClass\nN\n \nkind\n);\n\n\nN\n \nList\n?\n \nextends\n \nN\n \ntoList\n(\nClass\nN\n \nkind\n);\n\n\nN\n \nSet\n?\n \nextends\n \nN\n \ntoSet\n(\nClass\nN\n \nkind\n);\n\n\n\n\n\n\n\nNote\n\n\nEach of these methods also have an equivelant method with the suffix \nExplicit\n, we will discuss those later as they\nonly become important when we begin to discuss the differences between Typed Mode and Untyped Mode.\n\n\n\n\nEach of these methods has a slightly different behavior. For full details see the Ferma Javadocs for the Traversable\nclass. However, in short, the \nnext(Class)\n method returns any one of the matching elements and frames it as the\nspecified type. It will throw an exception however if no vertex are found. The \nnextOrDefault\n varient avoids the\nexception by returning the default value when there are no matches, which can be \n0\n or \nnull\n for example. Similarly\n\nnextOrAdd\n will add a new vertex to the underlying graph if the traversal yields no matches. Finally \nframe(Class)\n,\n\ntoList(Class)\n, and \ntoSet(Class)\n will return all elements that match the traversal as either a \nIterator\n, \nList\n, \nor \nSet\n.\n\n\nThe exact type returned from all the aforementioned calls will always be a Class of the type specified in the argument,\nor a subclass thereof. The exact type of the class instantiated will depend on which typing mode is being used.\n\n\nUntyped Mode\n\n\nIn untyped mode there is never any Java type information encoded into the underlying graph. This means when you take an\nobject off the graph there is no way for Ferma to know what Java type it is associated with and the user must select\nthe type manually. Since a Frame just defines a set of behaviors and properties exposed for a particular graph\nelement it can sometimes be useful to pick which Frame to use to represent an element based on how you need to interact\nwith that element rather than a one to one mapping of element to a specific type. In such a scenario Untyped Mode might\nbe the ideal choice.\n\n\nIn this mode when framing elements from a traversal the type of the element is determined entierly from the parameters\npassed to the methods invoked on the Traversable class. The following is an example of how to frame a vertex as a\n\nPerson\n class from above.\n\n\n// Open an untyped Framed Graph\n\n\nFramedGraph\n \nfg\n \n=\n \nnew\n \nDelegatingFramedGraph\n(\nTinkerGraph\n.\nopen\n());\n\n\n\n//create a vertex with no type information and a single name property\n\n\nVertexFrame\n \nvertex\n \n=\n \nfg\n.\naddFramedVertex\n(\nVertexFrame\n.\nclass\n);\n\n\nvertex\n.\nsetProperty\n(\nname\n,\n \nJeff\n);\n\n\n\n//retrieve the vertex we just created but this time frame it as a Person\n\n\nPerson\n \nperson\n \n=\n \nfg\n.\ntraverse\n(\ng\n \n-\n \ng\n.\nV\n().\nproperty\n(\nname\n,\n \njeff\n)).\nnextExplicit\n(\nPerson\n.\nclass\n);\n\n\nassert\n \nperson\n.\ngetName\n().\nequals\n(\nJeff\n);\n\n\n\n\n\n\n\nNote\n\n\nIn untyped mode all the \nTraversal\n methods with the suffix of \nExplicit\n behave exactly the same as those methods\nwithout the suffix. Therefore when working in untyped mode it is suggested you only use explicit methods. This way\nif you ever decide to migrate over to typed mode it will not change the behavior of your existing code base and will\nmake the migration process much easier. \n\n\n\n\nTyped Mode\n\n\nTyped mode takes things one step further and allows type information about a frame to be encoded as a\nproperty on vertex and edges in the underlying graph. This behavior is governed by the \nPolymorphicTypeResolver\n which\nencodes the type in a property name which defaults to the value of \nPolymorphicTypeResolver.TYPE_RESOLUTION_KEY\n but can\nbe explicitly set to any string value of the user's choice. When a class is framed the Type Resolution Key is read and\nthe original type is determined, this in turn effects the type used to instantiate the new Frame and may be a specific\ntype which is a subclass of the type requested. For example say we have the following model. \n\n\npublic\n \nclass\n \nPerson\n \nextends\n \nAbstractVertexFrame\n \n{\n\n \npublic\n \nString\n \ngetName\n()\n \n{\n\n \nreturn\n \nthis\n.\ngetProperty\n(\nname\n);\n\n \n}\n\n\n \npublic\n \nList\n?\n \nextends\n \nPerson\n \ngetFriends\n()\n \n{\n\n \nreturn\n \nthis\n.\ntraverse\n(\nv\n \n-\n \nv\n.\nout\n(\nfriend\n)).\ntoList\n(\nPerson\n.\nclass\n);\n\n \n}\n\n\n}\n\n\n\npublic\n \nclass\n \nProgrammer\n \nextends\n \nPerson\n \n{\n\n \n@Override\n\n \npublic\n \nList\n?\n \nextends\n \nProgrammer\n \ngetFriends\n()\n \n{\n\n \n//Programmers don\nt have friends :(\n\n \nreturn\n \nCollections\n.\nemptyList\n();\n\n \n}\n\n\n}\n\n\n\n\n\nIn this case we can encode a \nProgrammer\n vertex into the graph and even if we try to retrieve and frame that vertex as a\n\nVertexFrame\n or \nPerson\n in the future the instantiated type will still be \nProgrammer\n. This allows for a truly\npolymorphic Graph Data Model that leverages method overriding and class inheritance functiuonality in the model. For\nexample the following is possible now in Typed Mode.\n\n\n// Open a Framed Graph in Typed Mode\n\n\nFramedGraph\n \nfg\n \n=\n \nnew\n \nDelegatingFramedGraph\n(\nTinkerGraph\n.\nopen\n(),\n \ntrue\n,\n \nfalse\n);\n\n\n\n//create a vertex with type information specifying it as the Programmer type\n\n\nProgrammer\n \nprogrammer\n \n=\n \nfg\n.\naddFramedVertex\n(\nProgrammer\n.\nclass\n);\n\n\nprogrammer\n.\nsetName\n(\nJeff\n);\n\n\n\n//retrieve the vertex we just created and check it is instantiated as a Programer\n\n\nPerson\n \nperson\n \n=\n \nfg\n.\ntraverse\n(\ng\n \n-\n \ng\n.\nV\n().\nproperty\n(\nname\n,\n \njeff\n)).\nnext\n(\nPerson\n.\nclass\n);\n\n\nassert\n \nperson\n \ninstanceof\n \nProgrammer\n;\n\n\nassert\n \nperson\n.\ngetFriends\n().\nisEmpty\n();\n\n\n\n\n\nThe methods with the \nExplicit\n suffix are particularly meaningful for Typed Mode. In this mode they bypass the encoded\ntyping completely and instantiate the frame as if in Untyped Mode. The following code snippet provides an\nexample using the same model.\n\n\n// Open typed Framed Graph\n\n\nFramedGraph\n \nfg\n \n=\n \nnew\n \nDelegatingFramedGraph\n(\nTinkerGraph\n.\nopen\n(),\n \ntrue\n,\n \nfalse\n);\n\n\n\n//create a vertex with type information specifying it as the Programmer type\n\n\nProgrammer\n \nprogrammer\n \n=\n \nfg\n.\naddFramedVertex\n(\nProgrammer\n.\nclass\n);\n\n\nprogrammer\n.\nsetName\n(\nJeff\n);\n\n\n\n//retrieve the vertex we just created, since we are using an excplicit method the type won\nt be Programmer this time.\n\n\nPerson\n \nperson\n \n=\n \nfg\n.\ntraverse\n(\ng\n \n-\n \ng\n.\nV\n().\nproperty\n(\nname\n,\n \njeff\n)).\nnextExplicit\n(\nPerson\n.\nclass\n);\n\n\nassert\n \n!(\nperson\n \ninstanceof\n \nProgrammer\n);\n\n\n\n\n\nThe following are the list of explicit method types in the Traversable class.\n\n\nN\n \nN\n \nnextExplicit\n(\nClass\nN\n \nkind\n);\n\n\nN\n \nList\n?\n \nextends\n \nN\n \nnextExplicit\n(\nint\n \namount\n,\n \nClass\nN\n \nkind\n);\n\n\nN\n \nN\n \nnextOrDefaultExplicit\n(\nClass\nN\n \nkind\n,\n \nN\n \ndefaultValue\n);\n\n\nN\n \nN\n \nnextOrAddExplicit\n(\nClassInitializer\nN\n \ninitializer\n);\n\n\nN\n \nN\n \nnextOrAddExplicit\n(\nClass\nN\n \nkind\n);\n\n\nN\n \nIterator\n?\n \nextends\n \nN\n \nframeExplicit\n(\nClass\nN\n \nkind\n);\n\n\nN\n \nList\n?\n \nextends\n \nN\n \ntoListExplicit\n(\nClass\nN\n \nkind\n);\n\n\nN\n \nSet\n?\n \nextends\n \nN\n \ntoSetExplicit\n(\nClass\nN\n \nkind\n);\n\n\n\n\n\nIt is also possible to change the type encoded in the underlying graph after the element has already been created. The\nfollowing example demonstrates this feature.\n\n\nFramedGraph\n \nfg\n \n=\n \nnew\n \nDelegatingFramedGraph\n(\nTinkerGraph\n.\nopen\n(),\n \ntrue\n,\n \nfalse\n);\n\n\n\n//create a vertex with type information specifying it as the Programmer type\n\n\nProgrammer\n \nprogrammer\n \n=\n \nfg\n.\naddFramedVertex\n(\nProgrammer\n.\nclass\n);\n\n\nprogrammer\n.\nsetName\n(\nJeff\n);\n\n\n\n//retrieve the vertex we just created and check it is instantiated as a Programer\n\n\nPerson\n \nperson\n \n=\n \nfg\n.\ntraverse\n(\ng\n \n-\n \ng\n.\nV\n().\nproperty\n(\nname\n,\n \njeff\n)).\nnext\n(\nPerson\n.\nclass\n);\n\n\nassert\n \nperson\n \ninstanceof\n \nProgrammer\n;\n\n\n\n//change the type resolution to person\n\n\nperson\n.\nsetTypeResolution\n(\nPerson\n.\nclass\n);\n\n\n\n//retrieve the vertex again to show the type changed\n\n\nperson\n \n=\n \nfg\n.\ntraverse\n(\ng\n \n-\n \ng\n.\nV\n().\nproperty\n(\nname\n,\n \njeff\n)).\nnext\n(\nPerson\n.\nclass\n);\n\n\nassert\n(!(\nperson\n \ninstanceof\n \nProgrammer\n));\n\n\nassert\n(\nperson\n \ninstanceof\n \nPerson\n);", "title": "Object Mapping" }, { "location": "/object_mapping/#typing", - "text": "There are two typing modes for ferma and each significantly effects how the user will determine the type of the objects\npulled from the graph, these modes are called Typed Mode and Untyped Mode . When performing a traversal on a Frame there are several methods provided which automatically encapsulate the underlying\ngraph element or elements into a framed equivelant such as a VertexFrame or a EdgeFrame . This may either be a single\nFrame, Iterator , Set , or List of Frames. In the earlier example we used a traversal to find all the coworkers, we used the toList() method to frame all the\nunderlying vertex into the Person type. this . traverse ( v - v . out ( coworker )). toList ( Person . class ); Traversals have several different methods availible that each frame and collect the underlying elements in different\nways, those methods, members of the Traversable interface, are the following. N N next ( Class N kind ); N List ? extends N next ( int amount , Class N kind ); N N nextOrDefault ( Class N kind , N defaultValue ); VertexFrame nextOrAdd (); N N nextOrAdd ( ClassInitializer N initializer ); N N nextOrAdd ( Class N kind ); N Iterator N frame ( Class N kind ); N List ? extends N toList ( Class N kind ); N Set ? extends N toSet ( Class N kind ); Note Each of these methods also have an equivelant method with the suffix Explicit , we will discuss those later as they\nonly become important when we begin to discuss the differences between Typed Mode and Untyped Mode . Each of these methods has a slightly different behavior. For full details see the Ferma Javadocs for the Traversable\nclass. However, in short, the next(Class) method returns any one of the matching elements and frames it as the\nspecified type. It will throw an exception however if no vertex are found. The nextOrDefault varient avoids the\nexception by returning the default value when there are no matches, which can be 0 or null for example. Similarly nextOrAdd will add a new vertex to the underlying graph if the traversal yields no matches. Finally frame(Class) , toList(Class) , and toSet(Class) will return all elements that match the traversal as either a Iterator , List , \nor a Set . The exact type returned from all the aforementioned calls will always be a Class of the type specified in the argument,\nor a subclass thereof. The exact type of the class instantiated will depend on which typing mode is being used.", + "text": "There are two typing modes for ferma and each significantly effects how the user will determine the type of the objects\npulled from the graph, these modes are called Typed Mode and Untyped Mode . When performing a traversal on a frame there are several methods provided which automatically encapsulate the underlying\ngraph element or elements into a framed equivelant such as a VertexFrame or an EdgeFrame . This may be either a single\nframe, or a group of frames provided by an Iterator , Set , or List . In the earlier example we used a traversal to find all the coworkers and we used the toList() method to frame all the\nunderlying vertex into the Person type. this . traverse ( v - v . out ( coworker )). toList ( Person . class ); Traversals have several different methods availible that each frame and collect the underlying elements in different\nways, those methods, members of the Traversable interface, are the following. N N next ( Class N kind ); N List ? extends N next ( int amount , Class N kind ); N N nextOrDefault ( Class N kind , N defaultValue ); VertexFrame nextOrAdd (); N N nextOrAdd ( ClassInitializer N initializer ); N N nextOrAdd ( Class N kind ); N Iterator N frame ( Class N kind ); N List ? extends N toList ( Class N kind ); N Set ? extends N toSet ( Class N kind ); Note Each of these methods also have an equivelant method with the suffix Explicit , we will discuss those later as they\nonly become important when we begin to discuss the differences between Typed Mode and Untyped Mode. Each of these methods has a slightly different behavior. For full details see the Ferma Javadocs for the Traversable\nclass. However, in short, the next(Class) method returns any one of the matching elements and frames it as the\nspecified type. It will throw an exception however if no vertex are found. The nextOrDefault varient avoids the\nexception by returning the default value when there are no matches, which can be 0 or null for example. Similarly nextOrAdd will add a new vertex to the underlying graph if the traversal yields no matches. Finally frame(Class) , toList(Class) , and toSet(Class) will return all elements that match the traversal as either a Iterator , List , \nor Set . The exact type returned from all the aforementioned calls will always be a Class of the type specified in the argument,\nor a subclass thereof. The exact type of the class instantiated will depend on which typing mode is being used.", "title": "Typing" }, { @@ -92,7 +92,7 @@ }, { "location": "/object_mapping/#typed-mode", - "text": "Typed mode takes things one step further and allows type information about a frame to be encoded as a\nproperty on vertex and edges in the underlying graph. This behavior is governed by the PolymorphicTypeResolver which\nencodes the type in a property name which defaults to the value of PolymorphicTypeResolver.TYPE_RESOLUTION_KEY but can\nbe explicitly set to any string value of the user's choice. When a class is framed the Type Resolution Key is read and\nthe original type is determined, this in turn effects the type used to instantiate the new Frame and may be a specific\ntype which is a subclass of the type requested. For example say we have the following model. public class Person extends AbstractVertexFrame { \n public String getName () { \n return this . getProperty ( name ); \n } \n\n public List ? extends Person getFriends () { \n return this . traverse ( v - v . out ( friend )). toList ( Person . class ); \n } } public class Programmer extends Person { \n @Override \n public List ? extends Programmer getFriends () { \n //Programmers don t have friends :( \n return Collections . emptyList (); \n } } In this case we can encode a Programmer vertex into the graph and even if we try to retrieve and frame that vertex as a VertexFrame or Person in the future the instantiated type will still be Programmer . This allows for a truly\npolymorphic Graph Data Model that leverages method overriding and class inheritance functiuonality in the model. For\nexample the following is possible now in Typed Mode. // Open a Framed Graph in Typed Mode FramedGraph fg = new DelegatingFramedGraph ( TinkerGraph . open (), true , false ); //create a vertex with type information specifying it as the Programmer type Programmer programmer = fg . addFramedVertex ( Programmer . class ); programmer . setName ( Jeff ); //retrieve the vertex we just created and check it is instantiated as a Programer Person person = fg . traverse ( g - g . V (). property ( name , jeff )). next ( Person . class ); assert person instanceof Programmer ; assert person . getFriends (). isEmpty (); The methods with the Explicit suffix are particularly meaningful for Typed Mode. In this mode they bypass the encoded\ntyping completely and instantiate the frame as if in Untyped Mode. The following code snippet provides an\nexample using the same model. // Open typed Framed Graph FramedGraph fg = new DelegatingFramedGraph ( TinkerGraph . open (), true , false ); //create a vertex with no type information and a single name property Programmer programmer = fg . addFramedVertex ( Programmer . class ); programmer . setName ( Jeff ); //retrieve the vertex we just created, since we are using an excplicit method the type won t be Programmer this time. Person person = fg . traverse ( g - g . V (). property ( name , jeff )). nextExplicit ( Person . class ); assert !( person instanceof Programmer ); The following are the list of explicit method types in the Traversable class. N N nextExplicit ( Class N kind ); N List ? extends N nextExplicit ( int amount , Class N kind ); N N nextOrDefaultExplicit ( Class N kind , N defaultValue ); N N nextOrAddExplicit ( ClassInitializer N initializer ); N N nextOrAddExplicit ( Class N kind ); N Iterator ? extends N frameExplicit ( Class N kind ); N List ? extends N toListExplicit ( Class N kind ); N Set ? extends N toSetExplicit ( Class N kind ); It is also possible to change the type encoded in the underlying graph after the element has already been created. The\nfollowing example demonstrates this feature. FramedGraph fg = new DelegatingFramedGraph ( TinkerGraph . open (), true , false ); //create a vertex with type information specifying it as the Programmer type Programmer programmer = fg . addFramedVertex ( Programmer . class ); programmer . setName ( Jeff ); //retrieve the vertex we just created and check it is instantiated as a Programer Person person = fg . traverse ( g - g . V (). property ( name , jeff )). next ( Person . class ); assert person instanceof Programmer ; //change the type resolution to person person . setTypeResolution ( Person . class ); //retrieve the vertex again to show the type changed person = fg . traverse ( g - g . V (). property ( name , jeff )). next ( Person . class ); assert (!( person instanceof Programmer )); assert ( person instanceof Person );", + "text": "Typed mode takes things one step further and allows type information about a frame to be encoded as a\nproperty on vertex and edges in the underlying graph. This behavior is governed by the PolymorphicTypeResolver which\nencodes the type in a property name which defaults to the value of PolymorphicTypeResolver.TYPE_RESOLUTION_KEY but can\nbe explicitly set to any string value of the user's choice. When a class is framed the Type Resolution Key is read and\nthe original type is determined, this in turn effects the type used to instantiate the new Frame and may be a specific\ntype which is a subclass of the type requested. For example say we have the following model. public class Person extends AbstractVertexFrame { \n public String getName () { \n return this . getProperty ( name ); \n } \n\n public List ? extends Person getFriends () { \n return this . traverse ( v - v . out ( friend )). toList ( Person . class ); \n } } public class Programmer extends Person { \n @Override \n public List ? extends Programmer getFriends () { \n //Programmers don t have friends :( \n return Collections . emptyList (); \n } } In this case we can encode a Programmer vertex into the graph and even if we try to retrieve and frame that vertex as a VertexFrame or Person in the future the instantiated type will still be Programmer . This allows for a truly\npolymorphic Graph Data Model that leverages method overriding and class inheritance functiuonality in the model. For\nexample the following is possible now in Typed Mode. // Open a Framed Graph in Typed Mode FramedGraph fg = new DelegatingFramedGraph ( TinkerGraph . open (), true , false ); //create a vertex with type information specifying it as the Programmer type Programmer programmer = fg . addFramedVertex ( Programmer . class ); programmer . setName ( Jeff ); //retrieve the vertex we just created and check it is instantiated as a Programer Person person = fg . traverse ( g - g . V (). property ( name , jeff )). next ( Person . class ); assert person instanceof Programmer ; assert person . getFriends (). isEmpty (); The methods with the Explicit suffix are particularly meaningful for Typed Mode. In this mode they bypass the encoded\ntyping completely and instantiate the frame as if in Untyped Mode. The following code snippet provides an\nexample using the same model. // Open typed Framed Graph FramedGraph fg = new DelegatingFramedGraph ( TinkerGraph . open (), true , false ); //create a vertex with type information specifying it as the Programmer type Programmer programmer = fg . addFramedVertex ( Programmer . class ); programmer . setName ( Jeff ); //retrieve the vertex we just created, since we are using an excplicit method the type won t be Programmer this time. Person person = fg . traverse ( g - g . V (). property ( name , jeff )). nextExplicit ( Person . class ); assert !( person instanceof Programmer ); The following are the list of explicit method types in the Traversable class. N N nextExplicit ( Class N kind ); N List ? extends N nextExplicit ( int amount , Class N kind ); N N nextOrDefaultExplicit ( Class N kind , N defaultValue ); N N nextOrAddExplicit ( ClassInitializer N initializer ); N N nextOrAddExplicit ( Class N kind ); N Iterator ? extends N frameExplicit ( Class N kind ); N List ? extends N toListExplicit ( Class N kind ); N Set ? extends N toSetExplicit ( Class N kind ); It is also possible to change the type encoded in the underlying graph after the element has already been created. The\nfollowing example demonstrates this feature. FramedGraph fg = new DelegatingFramedGraph ( TinkerGraph . open (), true , false ); //create a vertex with type information specifying it as the Programmer type Programmer programmer = fg . addFramedVertex ( Programmer . class ); programmer . setName ( Jeff ); //retrieve the vertex we just created and check it is instantiated as a Programer Person person = fg . traverse ( g - g . V (). property ( name , jeff )). next ( Person . class ); assert person instanceof Programmer ; //change the type resolution to person person . setTypeResolution ( Person . class ); //retrieve the vertex again to show the type changed person = fg . traverse ( g - g . V (). property ( name , jeff )). next ( Person . class ); assert (!( person instanceof Programmer )); assert ( person instanceof Person );", "title": "Typed Mode" }, { diff --git a/object_mapping/index.html b/object_mapping/index.html index 5d5eae319b387445844d5c4512aa2799ae9cddcd..e878bc11a5f486ce5480c9f7300611b8598fc824 100644 --- a/object_mapping/index.html +++ b/object_mapping/index.html @@ -504,10 +504,10 @@ is to a Relational Database. That is to say that it maps Java Objects to edges a natural consequence the Java types become an implied Schema for a Graph Database even if the underlying implementation doesnt support the notion of a schema.</p> <p>The objects associated with the various types of Edges and Vertex in a graph are collectively called the Graph Data -Model (GDM). Each Java type in the GDM will usually represent a class of Edges or Vertex in underlying graph. All Edges -in the model will extend from the <code class="codehilite">EdgeFrame</code> interface and all vertex will extend from <code class="codehilite">VertexFrame</code> interface. The -individual classes that comprise the GDM are usually simply refered to as Frames.</p> -<p>The methods defined by a Frame will represent interactions with the underlying graph via traversals that are relative, +Model (GDM). Each Java type in the GDM will usually represent a class of Edges or Vertex in the underlying graph. All +Edges in the model will extend from the <code class="codehilite">EdgeFrame</code> interface and all vertex will extend from the <code class="codehilite">VertexFrame</code> +interface. The individual classes that comprise the GDM are usually simply refered to as frames.</p> +<p>The methods defined by a frame will represent interactions with the underlying graph via traversals that are relative, using the current edge or vertex as their starting point.</p> <div class="codehilite"><pre><span></span><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Person</span> <span class="kd">extends</span> <span class="n">VertexFrame</span> <span class="o">{</span> <span class="n">String</span> <span class="nf">getName</span><span class="o">();</span> @@ -551,10 +551,10 @@ with other vertex in the graph of the same type that represent their coworkers.< <h2 id="typing">Typing<a class="headerlink" href="#typing" title="Permanent link">¶</a></h2> <p>There are two typing modes for ferma and each significantly effects how the user will determine the type of the objects pulled from the graph, these modes are called <strong>Typed Mode</strong> and <strong>Untyped Mode</strong>.</p> -<p>When performing a traversal on a Frame there are several methods provided which automatically encapsulate the underlying -graph element or elements into a framed equivelant such as a <code class="codehilite">VertexFrame</code> or a <code class="codehilite">EdgeFrame</code>. This may either be a single -Frame, <code class="codehilite">Iterator</code>, <code class="codehilite">Set</code>, or <code class="codehilite">List</code> of Frames.</p> -<p>In the earlier example we used a traversal to find all the coworkers, we used the <code class="codehilite">toList()</code> method to frame all the +<p>When performing a traversal on a frame there are several methods provided which automatically encapsulate the underlying +graph element or elements into a framed equivelant such as a <code class="codehilite">VertexFrame</code> or an <code class="codehilite">EdgeFrame</code>. This may be either a single +frame, or a group of frames provided by an <code class="codehilite">Iterator</code>, <code class="codehilite">Set</code>, or <code class="codehilite">List</code>.</p> +<p>In the earlier example we used a traversal to find all the coworkers and we used the <code class="codehilite">toList()</code> method to frame all the underlying vertex into the <code class="codehilite">Person</code> type.</p> <div class="codehilite"><pre><span></span><span class="k">this</span><span class="o">.</span><span class="na">traverse</span><span class="o">(</span><span class="n">v</span> <span class="o">-></span> <span class="n">v</span><span class="o">.</span><span class="na">out</span><span class="o">(</span><span class="s">"coworker"</span><span class="o">)).</span><span class="na">toList</span><span class="o">(</span><span class="n">Person</span><span class="o">.</span><span class="na">class</span><span class="o">);</span> </pre></div> @@ -575,7 +575,7 @@ ways, those methods, members of the <code class="codehilite">Traversable</code> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Each of these methods also have an equivelant method with the suffix <code class="codehilite">Explicit</code>, we will discuss those later as they -only become important when we begin to discuss the differences between Typed Mode and <code class="codehilite">Untyped Mode</code>.</p> +only become important when we begin to discuss the differences between Typed Mode and Untyped Mode.</p> </div> <p>Each of these methods has a slightly different behavior. For full details see the Ferma Javadocs for the Traversable class. However, in short, the <code class="codehilite">next(Class)</code> method returns any one of the matching elements and frames it as the @@ -583,7 +583,7 @@ specified type. It will throw an exception however if no vertex are found. The < exception by returning the default value when there are no matches, which can be <code class="codehilite">0</code> or <code class="codehilite">null</code> for example. Similarly <code class="codehilite">nextOrAdd</code> will add a new vertex to the underlying graph if the traversal yields no matches. Finally <code class="codehilite">frame(Class)</code>, <code class="codehilite">toList(Class)</code>, and <code class="codehilite">toSet(Class)</code> will return all elements that match the traversal as either a <code class="codehilite">Iterator</code>, <code class="codehilite">List</code>, -or a <code class="codehilite">Set</code>.</p> +or <code class="codehilite">Set</code>.</p> <p>The exact type returned from all the aforementioned calls will always be a Class of the type specified in the argument, or a subclass thereof. The exact type of the class instantiated will depend on which typing mode is being used.</p> <h3 id="untyped-mode">Untyped Mode<a class="headerlink" href="#untyped-mode" title="Permanent link">¶</a></h3> @@ -664,7 +664,7 @@ example using the same model.</p> <div class="codehilite"><pre><span></span><span class="c1">// Open typed Framed Graph</span> <span class="n">FramedGraph</span> <span class="n">fg</span> <span class="o">=</span> <span class="k">new</span> <span class="n">DelegatingFramedGraph</span><span class="o">(</span><span class="n">TinkerGraph</span><span class="o">.</span><span class="na">open</span><span class="o">(),</span> <span class="kc">true</span><span class="o">,</span> <span class="kc">false</span><span class="o">);</span> -<span class="c1">//create a vertex with no type information and a single name property</span> +<span class="c1">//create a vertex with type information specifying it as the Programmer type</span> <span class="n">Programmer</span> <span class="n">programmer</span> <span class="o">=</span> <span class="n">fg</span><span class="o">.</span><span class="na">addFramedVertex</span><span class="o">(</span><span class="n">Programmer</span><span class="o">.</span><span class="na">class</span><span class="o">);</span> <span class="n">programmer</span><span class="o">.</span><span class="na">setName</span><span class="o">(</span><span class="s">"Jeff"</span><span class="o">);</span>