Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Classes all the way down #58

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
eb12cce
WIP: rewriting everything with inner classes
laughedelic Mar 26, 2016
bbec14a
Added source and target graphs to the edge parameters; otherwise sour…
laughedelic Mar 27, 2016
758be84
Returning VT.Vertex-like types; using .new Vertex() for that; .fromRa…
laughedelic Mar 28, 2016
e9bb8a1
Cleaned build well, now .fromRaw() works as expected; added a note ab…
laughedelic Mar 28, 2016
fbbaffd
Added arity-specific methods in/out-E/V methods with default implemen…
laughedelic Mar 28, 2016
7bb50cf
Moved all in/out methods from graph to Vertex class
laughedelic Mar 28, 2016
23ebbf0
Moved source/target, all propeties-related methods and addVertex/addE…
laughedelic Mar 28, 2016
f17a4e7
Just moved things from GraphSchema to TypedGraph (now it's one class)
laughedelic Mar 28, 2016
1a8b15a
Made top-level classes public, renamed files
laughedelic Mar 29, 2016
a41459e
Added TypedLinkGraph (not the best name, but will work for now)
laughedelic Mar 29, 2016
86b6145
Updated tests code; discovered that .fromRaw() doesn't return the exp…
laughedelic Mar 29, 2016
0f3f829
Rewrote index-related code; added two classes refining the interface …
laughedelic Mar 29, 2016
f9dc524
Made top-level entities explicitly public
laughedelic Mar 29, 2016
3226993
Added methods for all members instead of fields (except of the _label…
laughedelic Mar 30, 2016
604ddad
Added to ElementType properties set and made the properties factory m…
laughedelic Mar 30, 2016
d83494e
Added a set containing all vertex types of a graph (which are automat…
laughedelic Mar 30, 2016
0a8be61
Added a check on the set construction for distinct labels (if you try…
laughedelic Mar 30, 2016
e89f450
Added inner class Property to the ElementType
laughedelic Mar 30, 2016
6635419
Added UntypedGraphSchema interface for schema creation; separated tra…
laughedelic Mar 30, 2016
e3b59ae
Added sets for holding all graph's edge types and indexes
laughedelic Mar 30, 2016
94012e6
Merge branch 'feature/schema-creation' into refactoring/everything-is…
laughedelic Mar 30, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ javaVersion := "1.8"

excludeFilter in unmanagedSources :=
(excludeFilter in unmanagedSources).value ||
"*Query.java" ||
"*TwitterGraphTestSuite.java"
"*Query.java"

javacOptions ++= Seq(
"-Xdiags:verbose"
)
79 changes: 79 additions & 0 deletions src/main/java/com/bio4j/angulillos/Arity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.bio4j.angulillos;

interface HasArity {

/* the arity for this edge. This corresponds to the edge between the two vertex types. */
Arity arity();
}

/*
### Arities

We have six basic arities: three for in, three for out.
*/
public enum Arity {

oneToOne,
oneToAtMostOne,
oneToAtLeastOne,
oneToAny,

atMostOneToOne,
atMostOneToAtMostOne,
atMostOneToAtLeastOne,
atMostOneToAny,

atLeastOneToOne,
atLeastOneToAtMostOne,
atLeastOneToAtLeastOne,
atLeastOneToAny,

anyToOne,
anyToAtMostOne,
anyToAtLeastOne,
anyToAny;
}

/* #### In-arities */

/* An edge type `e` being _surjective_ implies that calling `inV(e)` will always return some, possibly several, vertices */
interface FromAtLeastOne extends HasArity {}
/* An edge type `e` being _from many_ implies that calling `inV(e)` will in general return more than one vertex */
interface FromOne extends HasArity {}
/* An edge type `e` being _from one_ implies that calling `inV(e)` will return at most one vertex */
interface FromAtMostOne extends HasArity {}

/* #### Out-arities */

/* That an edge type `e` being _always defined_ implies that calling `outV(e)` will always return some, possibly several, vertices */
interface ToAtLeastOne extends HasArity {}
/* An edge type `e` being _to many_ implies that calling `outV(e)` will in general return more than one vertex */
interface ToOne extends HasArity {}
/* An edge type `e` being _to one_ implies that calling `outV(e)` will return at most one vertex */
interface ToAtMostOne extends HasArity {}


/*
#### Arity combinations

These are all the possible combinations of the different arities. In the first line under `extends` you see those that correspond to `in`, and in the second one those that correspond to `out`
*/
interface OneToOne extends FromOne, ToOne { default Arity arity() { return Arity.oneToOne; } }
interface OneToAtMostOne extends FromOne, ToAtMostOne { default Arity arity() { return Arity.oneToAtMostOne; } }
interface OneToAtLeastOne extends FromOne, ToAtLeastOne { default Arity arity() { return Arity.oneToAtLeastOne; } }
interface OneToAny extends FromOne { default Arity arity() { return Arity.oneToAny; } }

interface AtMostOneToOne extends FromAtMostOne, ToOne { default Arity arity() { return Arity.atMostOneToOne; } }
interface AtMostOneToAtMostOne extends FromAtMostOne, ToAtMostOne { default Arity arity() { return Arity.atMostOneToAtMostOne; } }
interface AtMostOneToAtLeastOne extends FromAtMostOne, ToAtLeastOne { default Arity arity() { return Arity.atMostOneToAtLeastOne; } }
interface AtMostOneToAny extends FromAtMostOne { default Arity arity() { return Arity.atMostOneToAny; } }

interface AtLeastOneToOne extends FromAtLeastOne, ToOne { default Arity arity() { return Arity.atLeastOneToOne; } }
interface AtLeastOneToAtMostOne extends FromAtLeastOne, ToAtMostOne { default Arity arity() { return Arity.atLeastOneToAtMostOne; } }
interface AtLeastOneToAtLeastOne extends FromAtLeastOne, ToAtLeastOne { default Arity arity() { return Arity.atLeastOneToAtLeastOne; } }
interface AtLeastOneToAny extends FromAtLeastOne { default Arity arity() { return Arity.atLeastOneToAny; } }

interface AnyToOne extends ToOne { default Arity arity() { return Arity.anyToOne; } }
interface AnyToAtMostOne extends ToAtMostOne { default Arity arity() { return Arity.anyToAtMostOne; } }
interface AnyToAtLeastOne extends ToAtLeastOne { default Arity arity() { return Arity.anyToAtLeastOne; } }
interface AnyToAny extends HasArity { default Arity arity() { return Arity.anyToAny; } }
87 changes: 87 additions & 0 deletions src/main/java/com/bio4j/angulillos/EdgeType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.bio4j.angulillos;

/*
## Edges

A typed edge with explicit source and target.
*/
public abstract class EdgeType <
// source
ST extends VertexType<ST, SG,RV,RE>,
SG extends TypedGraph<SG,RV,RE>,
// edge itself
ET extends EdgeType<ST,SG, ET,EG, TT,TG, RV,RE>,
EG extends TypedGraph<EG,RV,RE>,
// target
TT extends VertexType<TT, TG,RV,RE>,
TG extends TypedGraph<TG,RV,RE>,
// raws
RV,RE
> extends ElementType<ET,EG,RE>
implements HasArity
{

private final ST sourceType;
public final ST sourceType() { return this.sourceType; }

private final TT targetType;
public final TT targetType() { return this.targetType; }

protected EdgeType(ST sourceType, TT targetType) {
this.sourceType = sourceType;
this.targetType = targetType;
}

// NOTE: this call is typesafe, but the compiler cannot check it here, because the RV type in self() is not bound to be the same as we use from the enclousing class context
@SuppressWarnings("unchecked")
/* This method should be used for constructing _all_ instances of the Edge inner class to get the precise return type */
public final ET.Edge fromRaw(RE raw) { return self().new Edge(raw); }

/* This method adds a new edge of this type to the graph */
public ET.Edge addEdge(
VertexType<ST, SG,RV,RE>.Vertex source,
VertexType<TT, TG,RV,RE>.Vertex target
) {
return fromRaw(
graph().raw().addEdge( source.raw(), this._label, target.raw() )
);
}


public class Edge extends Element {

// NOTE: this constructor is private to enforce the usage of the factory method fromRaw()
private Edge(RE raw) { super(raw); }


/* ### Properties */
@Override public
<X> X get(ET.Property<X> property) {
return graph().raw().<X>getPropertyE(this.raw(), property._label);
}

@Override public
<X> Edge set(ET.Property<X> property, X value) {

graph().raw().setPropertyE(this.raw(), property._label, value);
return this;
}


/* the source vertex of this edge */
public ST.Vertex source() {
return sourceType.fromRaw(
graph().raw().source( this.raw() )
);
}

/* the target vertex of this edge */
public TT.Vertex target() {
return targetType.fromRaw(
graph().raw().target( this.raw() )
);
}

}

}
87 changes: 87 additions & 0 deletions src/main/java/com/bio4j/angulillos/ElementType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.bio4j.angulillos;

import java.util.Set;
import java.util.HashSet;

/*
## Elements

This is a base interface for both [Vertices](TypedVertex.java.md) and [Edges](TypedEdge.java.md); it only has that which is common to both:

1. a reference to its [type](#Element_types) `ET`
2. methods for [properties](Property.java.md)
3. a reference to the [graph](TypedGraph.java.md) `G` of which they are elements.

#### elements and their types

`E` refers to the element itself, and `ET` its type. You cannot define one without defining the other.
*/
public abstract class ElementType <
FT extends ElementType<FT,G,RF>,
G extends TypedGraph<G,?,?>,
RF
>
{
/* This is a unique label */
public final String _label = getClass().getCanonicalName();

/* An abstract reference to the instance of the implementing class.
_This has to be **always** implemented in a non-abstract inheritor as `return this`._
It just cannot be implemented abstractly.
*/
protected abstract FT self();


/* The graph in which this element lives */
public abstract G graph();


abstract class Element {
private final RF raw;
public final RF raw() { return this.raw; }

public Element(RF raw) { this.raw = raw; }

public final FT type = ElementType.this.self();

/* The `get` method lets you get the value of a `property` which this element has. For that, you pass as an argument the [property](Property.java.md). Note that the type bounds only allow properties of this element. */
public abstract <X> X get(FT.Property<X> property);

/* `set` sets the value of a `property` for this element. Again, you can only set properties that this element has, using values of the corresponding property value type. */
public abstract <X> Element set(FT.Property<X> property, X value);
}


/* This set stores all properties that are defined on this element type */
private Set<Property<?>> properties = new HashSet<>();
public final Set<Property<?>> properties() { return this.properties; }

/* Defines a new property on this element type and adds it to the `properties` set */
public final <X> Property<X> property(String nameSuffix, Class<X> valueClass) {
return new Property<X>(nameSuffix, valueClass);
}

/* This inner class fixes the element type */
public final class Property<X> extends com.bio4j.angulillos.Property<FT,X> {

// NOTE: this constructor is private to enforce usage of the factory method `property`
private Property(String nameSuffix, Class<X> valueClass) {
super(ElementType.this.self(), nameSuffix, valueClass);

if (
ElementType.this.properties.removeIf( (Property<?> p) ->
p._label.equals( this._label )
)
) {
throw new IllegalArgumentException(
"Element type [" +
ElementType.this._label +
"] contains duplicate property: " +
this._label
);
} else {
ElementType.this.properties.add(this);
}
}
}
}
Loading