Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
MatrixEditor committed Dec 10, 2023
0 parents commit 3bfafa0
Show file tree
Hide file tree
Showing 38 changed files with 3,269 additions and 0 deletions.
34 changes: 34 additions & 0 deletions .github/workflows/build-gradle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle

name: Java CI with Gradle

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

permissions:
contents: read

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
- name: Build with Gradle
uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0
with:
arguments: build
31 changes: 31 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
### IntelliJ IDEA ###
out/
!**/src/main/**/out/
!**/src/test/**/out/
.idea/
*.iml

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/

### Mac OS ###
.DS_Store
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2022 Proto4j

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
114 changes: 114 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Proto4j-Objection

![Module](https://img.shields.io:/static/v1?label=Module&message=objection&color=9cf)
![Build](https://img.shields.io:/static/v1?label=Build&message=passing&color=green)

This repository contains the source code for the `Objection` module from `Proto4j`. It is considered to be a development repository where changes can be made and features can be requested. The source code is heavily documented as there will be no external documentation. A simple usage of this module is presented below.


### Basic Usage

---

There are two possibilities on how to write code that will be serializable by this module:

1. Use standard `Java` directives
2. Use pre-defined `Annotations` on declared classes and fields.
further
This small overview tries to show both versions as detailed as possible. Nested serializable types will be automatically detected. Yet, there are some standard types defined to be serialized and de-serialized - they can be found in the following table:

| Class | Serializable | Serializer-Class |
|------------|--------------|------------------------------------------------|
| String | `true` | `StringSerializer` |
| Number | `true` | located as inner class in `NumberSerializer` |
| Collection | `true` | located as inner class in `SequenceSerializer` |
| Map | `true` | located as inner class in `SequenceSerializer` |
| Array | `true` | located as inner class in `SequenceSerializer` |
| MultiArray | `false` | --- |

If you use a class that is not included in that table, you can write your own `ObjectSerializer` implementation and integrate that into the serialization process.

#### UseCase 1: Basic class declaration rules

```java
// Traditional way with Java directives
class Car implements Serializable {
// All fields excluding compiler-generated, static and transient
// fields are going to be serialized.
private int id;
private String name;

// Use the transient keyword to prevent a field from being serialized
private transient String ignoredField;
}

// Annotated way: Use the @Version annotation on a class to set a global
// version. Here, the field address is ignored, because version 0 is used.
@Serialize
class Person {
// You can use a version flag to exclude fields from newer versions
// and make the code backwards compatible. No version points to the
// initial version, which is 0.
private String name;
private Car car;
@Version(1) private String address;

}
```

#### UseCase 2: Serialization process

```java
public static void main(String[] args) {
// At first, create a new Marshaller instance for the target type.
Marshaller<Car> marshaller = Objection.createMarshaller();
ByteArrayOutputStream output = new ByteArrayOutputStream();

// Secondly, create the instance that will be serialized
Car car = new Car(1, "Mustang"); // constructor (int, String) has to be defined
DataOutput = new DataOutputStream(output);

// Thirdly, serialize the object
OSharedConfiguration config = marshaller.marshall(car, output);

// With the returned configuration the output can be de-serialized back
// into a Car instance.
DataInput input = new DataInputStream(new ByteArrayInputStream(output.toByteArray()));
Car car2 = marshaller.unmarshall(input, config);
}
```

#### UseCase 3: Custom ObjectSerializer implementations

```java
// Example class that can read/write the previous defined Car.class which is used
// in the Person class.
class CarSerializer extends BasicObjectSerializer {
@Override
public boolean accept(Class<?> type) {
// return type == Car.class, or even better:
return Car.class.isAssignableFrom(type);
}

@Override
public void writeObject(DataOutput dataOutput, Object writableObject, OSerializationContext ctx)
throws IOException {
Car car = (Car) writableObject;
dataOutput.writeInt(car.getId());
dataOutput.writeInt(car.getName().length());
dataOutput.writeBytes(car.getName());
}

@Override
public Object getInstance(Class<?> type, DataInput dataInput, OSerializationContext ctx)
throws IOException {
int id = dataInput.readInt();
int name_length = dataInput.readInt();
byte[] name = new byte[name_length];

dataInput.readFully(name);
return new Car(id, new String(name));
}
}

```
46 changes: 46 additions & 0 deletions src/main/java/io/github/proto4j/objection/AbstractMarshaller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* MIT License
*
* Copyright (c) 2022 Proto4j
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package io.github.proto4j.objection; //@date 27.08.2022


public abstract class AbstractMarshaller<V> implements Marshaller<V> {

private OSharedConfiguration configuration;

public AbstractMarshaller() {
this(Objection.getDefaultConfiguration());
}

// ENHANCEMENT: add nonNull()-check before setting the variable.
public AbstractMarshaller(OSharedConfiguration configuration) {this.configuration = configuration;}

public OSharedConfiguration getConfiguration() {
return configuration;
}

public void setConfiguration(OSharedConfiguration configuration) {
this.configuration = configuration;
}
}
94 changes: 94 additions & 0 deletions src/main/java/io/github/proto4j/objection/BasicMarshaller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* MIT License
*
* Copyright (c) 2022 Proto4j
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package io.github.proto4j.objection; //@date 27.08.2022

import io.github.proto4j.objection.model.OClass;
import io.github.proto4j.objection.model.OField;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.InvalidClassException;
import java.lang.reflect.Field;
import java.util.Objects;

public class BasicMarshaller<V> extends AbstractMarshaller<V> {

public BasicMarshaller() {
}

public BasicMarshaller(OSharedConfiguration configuration) {
super(configuration);
}

/**
* {@inheritDoc}
*/
@Override
public OSharedConfiguration marshall(V value, DataOutput output) throws IOException, ReflectiveOperationException {
Objects.requireNonNull(value);
Objects.requireNonNull(output);

ObjectSerializer sr = getConfiguration().forType(OClass.class);
if (sr == null) {
throw new InvalidClassException("No OClass serializer specified");
}

getConfiguration().addType(value.getClass());
OClass<V> cls = OClass.klass(value, getConfiguration());

Object o = Objects.requireNonNull(cls.getInstance());
for (OField field : cls.getDeclaredFields()) {
if (field.getValue() == null) {
Field linked = field.getLinkedField();
linked.setAccessible(true);
field.setValue(linked.get(o));
}
}

OSerializationContext ctx = new BasicSerializationContext(cls, null, getConfiguration());
sr.writeObject(output, cls, ctx);
return getConfiguration();
}

/**
* {@inheritDoc}
*/
@Override
public OClass<V> unmarshall(DataInput input, OSharedConfiguration configuration) throws IOException {
Objects.requireNonNull(input);
Objects.requireNonNull(configuration);

setConfiguration(configuration);
ObjectSerializer sr = getConfiguration().forType(OClass.class);
if (sr == null) {
throw new InvalidClassException("No OClass serializer specified");
}

OSerializationContext ctx = new BasicSerializationContext(null, null, getConfiguration());
//noinspection unchecked
return (OClass<V>) sr.getInstance(OClass.class, input, ctx);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* MIT License
*
* Copyright (c) 2022 Proto4j
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package io.github.proto4j.objection; //@date 25.08.2022

import java.io.DataInput;
import java.io.IOException;

public abstract class BasicObjectSerializer implements ObjectSerializer {

/**
* {@inheritDoc}
*/
@Override
public Object getInstance(Class<?> type, DataInput dataInput, OSerializationContext ctx) throws IOException {
return null;
}

/**
* {@inheritDoc}
*/
@Override
public boolean accept(Class<?> type) {
return true;
}

}
Loading

0 comments on commit 3bfafa0

Please sign in to comment.