Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/henneberger/typekin
Structural typing for object graphs in Java
https://github.com/henneberger/typekin
Last synced: about 1 month ago
JSON representation
Structural typing for object graphs in Java
- Host: GitHub
- URL: https://github.com/henneberger/typekin
- Owner: henneberger
- License: apache-2.0
- Created: 2021-01-31T08:22:29.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2021-02-05T21:11:18.000Z (almost 4 years ago)
- Last Synced: 2023-07-26T21:57:49.291Z (over 1 year ago)
- Language: Java
- Size: 83 KB
- Stars: 13
- Watchers: 3
- Forks: 36
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Object Graphs and Structural Typing in Java
This gives Java a way to handle partial representations of data model while remaining type safe.
Types are generated at compile time via annotations.## Getting started
```xml
com.github.henneberger
typekin-processor
1.0.2
provided
```
## Example Usage
```java
public class Main {
// The optional model definition. If present, all TypeOf
// annotations must match this structure.
//
// You add `implements St{name}Model`
@Model
abstract class Foo implements StFooModel {
public abstract String getA();
public abstract String getB();
public abstract String getC();
}//A subset of the model (for code reuse)
@TypeOf(model = Foo.class)
public interface FooAFragment {
String getA();
}
@TypeOf(model = Foo.class)
public interface FooABFragment {
String getA();
String getB();
}
@TypeOf(model = Foo.class)
public interface FooCFragment {
String getC();
}
//compile error, D is not a property of the model
//@TypeOf(clazz = Foo.class)
//public interface FooDFragment {
// String getD();
//}// A container of data that can contain any data.
// Function signatures are used to determine
// equivalence classes with TypeOf classes.
//
// You add `implements St{name}`
@StructuralType(model = Foo.class)
public static class FooAData implements StFooAData {
public String getA() { return "A"; }
}
@StructuralType(model = Foo.class)
public static class FooABData implements StFooABData {
public String getA() { return "A"; }
public String getB() { return "B"; }
}
@StructuralType(model = Foo.class)
public static class FooCData implements StFooCData {
public String getC() { return "C"; }
}public static void main(String[] args) {
print(new FooAData());
print(new FooABData());
//print(new FooCData()); //compile error
}public static void print(FooAFragment foo) {
System.out.println(foo.getA());
//System.out.println(foo.getB()); //compile error
//System.out.println(foo.getC()); //compile error
}
}//This gets generated by the annotations:
interface StFooAData extends FooAFragment {}
interface StFooABData extends FooAFragment, FooABFragment {}
interface StFooCData extends FooCFragment {}interface StFooModel extends FooAFragment, FooABFragment, FooCFragment {}
interface StFooRef extends StFooAData, StFooABData, StFooCData {}
```### `@Model`
The `@Model` annotation defines the data model. All `@TypeOf` model fragments that
refer to a `@Model` class will be strongy typed. Only abstract methods will be recognized
for type candidates. For nested objects, a generated `Ref` class serves as a type reference.
Parameters:
- `name`: The name of the class it will generate
- `refName`: The name of the class it will generate for data model relationships
- `concreteName`: The name of the empty concrete class for jvm type validationE.g.
```java
@Model(name = "FooModel", refName = "FooRef")
abstract class Foo implements FooModel {
public abstract String getA();
public abstract List getBar();
}@Model(name = "BarModel", refName = "BarRef")
abstract class Bar implements BarModel {
public abstract String getA();
public abstract FooRef getFoo();
}
```### `@TypeOf`
The `@TypeOf` annotation defines a partial representation of the data model. All `@StructuralType`
classes that have the same model class are compared structurally to all `@TypeOf` interfaces.
Parameters:
- `model`: The class of the modelE.g:
```java
@TypeOf(model = Foo.class)
public interface FooFragment {
String getA();
List extends BarFragment> getBar();
}
@TypeOf(model = Bar.class)
public interface BarFragment {
String getA();
FooFragment getFoo();
}
```### `@StructuralType`
A concrete type that contains data. This can contain any data but only method signatures
that match the model will be used as candidates for `@TypeOf` classes.
Parameters:
- `model`: The class of the model
- `name`: The name of the class it will generateE.g.
```java
@StructuralType(model = Foo.class, name = "FooDataType")
public class FooData extends FooDataType {
public String getA() { return null; }
public List getBar() { return null; }
public String extraParam() { return null; } //ok
}
@StructuralType(model = Bar.class, name = "BarDataType")
public class BarData extends BarDataType {
public String getA() { return null; }
public Foo getFoo() { return null; }
}
```A full example can be found here:
[tests/src/main/java/com/github/henneberger/typekin/tests/example/FooExample.java](tests/src/main/java/com/github/henneberger/typekin/tests/example/FooExample.java)### Limitations
Since it relies on compile time annotations, other annotations may not work with Typekin.### Contributions
This work is inspiried by https://github.com/tlamr/stjava