Skip to content

Commit

Permalink
#71 documentation update
Browse files Browse the repository at this point in the history
  • Loading branch information
DirkMahler committed Jun 23, 2014
1 parent 01f13a5 commit 25006eb
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 57 deletions.
18 changes: 9 additions & 9 deletions doc/src/main/asciidoc/index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ graph database Neo4j.
= Core Concepts
== Static vs. Dynamic Composition

An example from a well known domain shall be used to explain the difference between both concepts of composition:
A simple example shall be used to explain the difference between both concepts of composition:

Person.java
[source,java]
.Person.java
----
@DatastoreEntity // A datastore specific annotation marking this interface as an entity
public interface Person {
Expand All @@ -37,26 +37,26 @@ public interface Person {
}
----

Actor.java
[source,java]
.Actor.java
----
@DatastoreEntity
public interface Actor extends Person {
List<Movie> getActedIn();
}
----

Director.java
[source,java]
.Director.java
----
@DatastoreEntity
public interface Director extends Person {
List<Movie> getDirected();
}
----

Movie.java
[source,java]
.Movie.java
----
@DatastoreEntity
public interface Movie {
Expand All @@ -72,8 +72,8 @@ public interface Movie {

Using the XO API the following use case can be implemented:

RaidersOfTheLostArk.java
[source,java]
.RaidersOfTheLostArk.java
----
public class RaidersOfTheLostArk {
Expand Down Expand Up @@ -118,8 +118,8 @@ public class RaidersOfTheLostArk {
The types Actor and Director use static composition by extending from the type Person. But what happens if a person
works in both roles: actor and director? A new type extending from both would be required if static composition was used:

DirectingActor.java
[source,java]
.DirectingActor.java
----
@DatastoreEntity
public interface DirectingActor extends Director, Actor {
Expand All @@ -129,8 +129,8 @@ public interface DirectingActor extends Director, Actor {
The situation gets even more complex if other roles (like screenwriter, editor, etc.) are added to the domain model.
Each combination of roles must be represented by such a type. Dynamic composition helps getting around this problem:

TempleOfDoom.java
[source,java]
.TempleOfDoom.java
----
public class TempleOfDoom {
Expand Down Expand Up @@ -169,8 +169,8 @@ above example the fact that the director also acted in the movie might have been
has been created using the type Director. XO offers a way to perform a migration at runtime and allows adding (or
removing) roles (i.e. types):

TempleOfDoom.java
[source,java]
.TempleOfDoom.java
----
public class TempleOfDoom {
Expand Down
91 changes: 69 additions & 22 deletions neo4j/src/main/asciidoc/index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ If a node has a label it can be assumed that it represents some type of data whi
properties and relationships (e.g. property "name" for persons, "ACTED_IN" relations to movies). This implies that a
Neo4j label can be represented as a Java interface and vice versa.

Person.java
[source,java]
.Person.java
----
@Label("Person") // The value "Person" can be omitted, in this case the class name is used
public interface Person {
Expand All @@ -48,8 +48,8 @@ public interface Person {
== Maven Dependencies
The Neo4j datastore for eXtended Objects is available from Maven Central and can be specified as dependency in pom.xml files:

pom.xml
[source,xml]
.pom.xml
----
<project ...>
...
Expand Down Expand Up @@ -83,8 +83,8 @@ An XO descriptor is a XML file located as classpath resource under "/META-INF/xo
Each must be uniquely identified by a name. This is similar to the persistence unit approach defined by the Java Persistence
API (JPA). The following snippet shows a minimum setup:

META-INF/xo.xml
[source,xml]
.META-INF/xo.xml
----
<v1:xo version="1.0" xmlns:v1="http://buschmais.com/xo/schema/v1.0">
<xo-unit name="movies">
Expand Down Expand Up @@ -112,8 +112,8 @@ types::

An XOManagerFactory instance can now be obtained as demonstrated in the following snippet:

Main.java
[source,java]
.Main.java
----
public class Main {
Expand All @@ -130,8 +130,8 @@ public class Main {

It is also possible to create a XOManagerFactory using an instance of the class 'com.buschmais.xo.api.XOUnit':

Main.java
[source,java]
.Main.java
----
public class Main {
Expand Down Expand Up @@ -170,8 +170,8 @@ Neo4j allows adding one or more labels to a node. These labels are used by eXten
type(s) a node is representing. Thus for each label that shall be used by the application a corresponding interface type must be created
which is annotated with @Label.

Person.java
[source,java]
.Person.java
----
@Label
public interface Person {
Expand All @@ -189,8 +189,8 @@ It can also be seen that a label usually enforces the presence of specific prope
property - starting with a lower case letter - is used to store its value in the database, this can be overwritten using @Property. The
following example demonstrates explicit mappings for a label and a property:

Person.java
[source,java]
.Person.java
----
@Label("MyPerson")
public interface Person {
Expand All @@ -208,8 +208,8 @@ The mapping of relations will be covered later.

A labeled type can extend from one or more labeled types.

Actor.java
[source,java]
.Actor.java
----
@Label
public interface Actor extends Person {
Expand All @@ -226,8 +226,8 @@ There might be situations where the same properties or relations shall be re-use
used, these are just interfaces specifying properties and relations which shall be shared. The following example demonstrates how the
property name of the labeled type Person is extracted to a template type:

Named.java
[source,java]
.Named.java
----
public interface Named {
Expand All @@ -237,8 +237,8 @@ public interface Named {
}
----

Person.java
[source,java]
.Person.java
----
@Label
public interface Person extends Named {
Expand All @@ -250,8 +250,8 @@ public interface Person extends Named {
A node can directly reference other nodes using relation properties. A property of a labeled type or template type is treated as such if it
references another labeled type or a collection thereof.

Movie.java
[source,java]
.Movie.java
----
@Label
public interface Movie {
Expand All @@ -262,8 +262,8 @@ public interface Movie {
}
----

Actor.java
[source,java]
.Actor.java
----
@Label
public interface Actor extends Person {
Expand All @@ -277,8 +277,8 @@ If no further mapping information is provided an outgoing unidirectional relatio
the property is assumed. The name may be specified using the @Relation annotation with the desired value. Furthermore
using one of the annotations @Outgoing or @Incoming the direction of the relation can be specified.

Actor.java
[source,java]
.Actor.java
----
@Label
public interface Actor extends Person {
Expand Down Expand Up @@ -310,8 +310,8 @@ unidirectional relations which map to the same relation type; one of them annota
The recommended way is to use an annotation which qualifies the relation and holds the mapping information at a single
point:

ActedIn.java
[source,java]
.ActedIn.java
----
@Relation
@Retention(RUNTIME)
Expand All @@ -320,8 +320,8 @@ public @interface ActedIn {
----


Actor.java
[source,java]
.Actor.java
----
@Label
public interface Actor extends Person {
Expand All @@ -334,8 +334,8 @@ public interface Actor extends Person {
----


Movie.java
[source,java]
.Movie.java
----
@Label
public interface Movie {
Expand All @@ -356,8 +356,8 @@ public interface Movie {
If a relation between two nodes shall have properties a dedicated type must be declared. It must contain two properties
returning the types of referenced types which are annotated with @Incoming and @Outgoing:

Directed.java
[source,java]
.Directed.java
----
@Relation
public interface Directed {
Expand All @@ -377,8 +377,8 @@ public interface Directed {
}
----

Director.java
[source,java]
.Director.java
----
@Label
public interface Director extends Person {
Expand All @@ -389,8 +389,8 @@ public interface Director extends Person {
----


Movie.java
[source,java]
.Movie.java
----
@Label
public interface Movie {
Expand All @@ -407,8 +407,8 @@ public interface Movie {
Note: If the typed relation references the same labeled type at both ends then the according properties of the latter
must also be annotated with @Outgoing and @Incoming:

Directed.java
[source,java]
.Directed.java
----
@Relation
public interface References {
Expand All @@ -427,8 +427,8 @@ public interface References {
}
----

Movie.java
[source,java]
.Movie.java
----
@Label
public interface Movie {
Expand All @@ -449,8 +449,8 @@ Typed relations may also be constructed using <<TemplateTypes>>, i.e. types whic

Labeled types or relation types may also define methods which execute a query on invocation and return the result:

Movie.java
[source,java]
.Movie.java
----
@Label
public interface Movie {
Expand All @@ -469,4 +469,51 @@ public interface Movie {

==== Transient Properties

Properties of entities or relations can be declared as transient, i.e. they may be used at runtime but will not be stored in the database:

[source,java]
.Person.java
----
@Label
public interface Person {
@Transient
String getName();
void setName();
}
----

==== User defined methods

It can be useful to provide a custom implementation of a method which has direct access to the underlying datatypes. This can be achieved using '@ImplementedBy'.

[source,java]
.Person.java
----
@Label
public interface Person {
@ImplementedBy(SetNameMethod.class)
String setName(String firstName, String lastName);
}
----

[source,java]
.SetNameMethod.java
----
public class SetNameMethod implements ProxyMethod<Node> {
@Override
public Object invoke(Node node, Object instance, Object[] args) {
String firstName = (String) args[0];
String lastName = (String) args[1];
String fullName = firstName + " " + lastName;
node.setProperty("name", fullName);
return fullName;
}
}
----
Loading

0 comments on commit 25006eb

Please sign in to comment.