Skip to content

Commit 741ea2b

Browse files
committed
Merge branch 'scijava/scijava-persist/init'
From @NicoKiaru: This PR brings a scijava service DefaultScijavaAdapterService which provides a way to serialize and deserialize java objects. Vocabulary : adapter = serializer (object to text) + deserializer (text to object) The most meaningful demo is in SerializationTests.java. A test is included, which basically makes a loop: object -> serialization -> string1 -> deserialization -> object -> serialization -> string2, and checks that string1.equals(string2) Scijava persist uses Gson serialization ( with RunTime adapters, which provide a way to serialize/deserialize objects extending abstract class or implements interface, see javadoc of RuntimeTypeAdapterFactory), and discovers and registers adapters at runtime. The adapters which are autodiscovered are of two kinds: IClassAdapter IClassRuntimeAdapter for adapters which require runtime adaptation (is this RealTransform object an affine transform ? or a sequence of transform, or a thinplateSplineTransform ? One runtime adapter needs to be registered per class) See #30
2 parents c3db7f1 + ba994cb commit 741ea2b

18 files changed

+1030
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ target/
55
.classpath
66
.project
77
.settings/
8+
9+
# IntelliJ #
10+
.idea/
11+
.iml

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
<modules>
4848
<module>imagej/imagej-ops2</module>
4949
<module>imagej/imagej-testutil</module>
50+
<module>scijava/scijava-persist</module>
5051
<module>scijava/scijava-ops</module>
5152
<module>scijava/scijava-testutil</module>
5253
<module>scijava/scijava-types</module>

scijava/scijava-persist/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/.classpath
2+
/.project
3+
/.settings/
4+
/.idea/
5+
/target/
6+
*.iml

scijava/scijava-persist/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#Scijava mechanism for object serialization
2+
3+
This incubator contains a mechanism that uses Scijava extensibility mechanism in order to register adapters that can be dispatched in multiple repositories.
4+
5+
Internally the Gson library is used with `RunTimeAdapters`, which allow to serialize interfaces.
6+
7+
TODO:
8+
* simple examples
9+
* tests
10+
* think about safety, or at least debugging ease (put a UUID)

scijava/scijava-persist/pom.xml

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
5+
http://maven.apache.org/xsd/maven-4.0.0.xsd">
6+
<modelVersion>4.0.0</modelVersion>
7+
8+
<parent>
9+
<groupId>org.scijava</groupId>
10+
<artifactId>scijava-incubator</artifactId>
11+
<version>0-SNAPSHOT</version>
12+
<relativePath>../..</relativePath>
13+
</parent>
14+
15+
<artifactId>scijava-persist</artifactId>
16+
17+
<name>SciJava Persist</name>
18+
<description>Extensible serialization mechanism for persisting objects.</description>
19+
<url>None</url>
20+
<inceptionYear>2021</inceptionYear>
21+
<organization>
22+
<name>SciJava</name>
23+
<url>https://scijava.org/</url>
24+
</organization>
25+
<licenses>
26+
<license>
27+
<name>Simplified BSD License</name>
28+
<distribution>repo</distribution>
29+
</license>
30+
</licenses>
31+
32+
33+
<developers>
34+
<developer>
35+
<id>nicokiaru</id>
36+
<name>Nicolas Chiaruttini</name>
37+
<url>https://www.epfl.ch/research/facilities/ptbiop/staff/</url>
38+
<roles>
39+
<role>founder</role>
40+
<role>lead</role>
41+
<role>developer</role>
42+
<role>debugger</role>
43+
<role>reviewer</role>
44+
<role>support</role>
45+
<role>maintainer</role>
46+
</roles>
47+
</developer>
48+
</developers>
49+
<contributors>
50+
<contributor>
51+
<name>Nicolas Chiaruttini</name>
52+
<url>http://biop.epfl.ch/INFO_Facility.html</url>
53+
<roles><role>founder</role></roles>
54+
<properties><id>NicoKiaru</id></properties>
55+
</contributor>
56+
</contributors>
57+
58+
<mailingLists>
59+
<mailingList>
60+
<name>Image.sc Forum</name>
61+
<archive>https://forum.image.sc/tag/scijava</archive>
62+
</mailingList>
63+
</mailingLists>
64+
65+
<scm>
66+
<connection>scm:git:git://github.com/scijava/incubator</connection>
67+
<developerConnection>scm:git:[email protected]:scijava/incubator</developerConnection>
68+
<tag>HEAD</tag>
69+
<url>https://github.com/scijava/incubator</url>
70+
</scm>
71+
72+
<issueManagement>
73+
<system>GitHub Issues</system>
74+
<url>https://github.com/scijava/scijava-testutil/issues</url>
75+
</issueManagement>
76+
<ciManagement>
77+
<system>Travis CI</system>
78+
<url>https://travis-ci.org/scijava/incubator</url>
79+
</ciManagement>
80+
81+
82+
<properties>
83+
<main-class>org.scijava.persist.Main</main-class>
84+
<package-name>org.scijava.persist</package-name>
85+
86+
<license.licenseName>bsd_2</license.licenseName>
87+
<license.copyrightOwners>SciJava developers.</license.copyrightOwners>
88+
</properties>
89+
90+
<repositories>
91+
<repository>
92+
<id>scijava.public</id>
93+
<url>https://maven.scijava.org/content/groups/public</url>
94+
</repository>
95+
</repositories>
96+
97+
<build>
98+
<plugins>
99+
<plugin>
100+
<groupId>com.alexecollins.maven.plugin</groupId>
101+
<artifactId>script-maven-plugin</artifactId>
102+
</plugin>
103+
</plugins>
104+
</build>
105+
<dependencies>
106+
<dependency>
107+
<groupId>org.scijava</groupId>
108+
<artifactId>scijava-common</artifactId>
109+
</dependency>
110+
111+
<dependency>
112+
<groupId>com.google.code.gson</groupId>
113+
<artifactId>gson</artifactId>
114+
<version>2.8.6</version>
115+
</dependency>
116+
117+
<!--- Test dependencies -->
118+
<dependency>
119+
<groupId>junit</groupId>
120+
<artifactId>junit</artifactId>
121+
<scope>test</scope>
122+
</dependency>
123+
</dependencies>
124+
</project>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
open module org.scijava.persist {
2+
3+
exports org.scijava.persist;
4+
5+
requires transitive com.google.gson;
6+
requires org.scijava;
7+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
2+
package org.scijava.persist;
3+
4+
import org.scijava.Context;
5+
import org.scijava.Priority;
6+
import org.scijava.plugin.AbstractPTService;
7+
import org.scijava.plugin.Parameter;
8+
import org.scijava.plugin.Plugin;
9+
import org.scijava.plugin.PluginInfo;
10+
import org.scijava.service.Service;
11+
12+
import java.util.List;
13+
14+
/**
15+
* Scijava service which provides the different Scijava Adapters available in
16+
* the current context. {@link IObjectScijavaAdapter} plugins are automatically
17+
* discovered and accessible in this service. In practice, serializer /
18+
* deserializers are obtained via {@link ScijavaGsonHelper} helper class
19+
*
20+
* @author Nicolas Chiaruttini, EPFL, 2021
21+
*/
22+
@Plugin(type = Service.class)
23+
public class DefaultScijavaAdapterService extends
24+
AbstractPTService<IObjectScijavaAdapter> implements
25+
IObjectScijavaAdapterService
26+
{
27+
28+
@Override
29+
public Class<IObjectScijavaAdapter> getPluginType() {
30+
return IObjectScijavaAdapter.class;
31+
}
32+
33+
@Parameter
34+
Context ctx;
35+
36+
@Override
37+
public Context context() {
38+
return ctx;
39+
}
40+
41+
@Override
42+
public Context getContext() {
43+
return ctx;
44+
}
45+
46+
double priority = Priority.NORMAL;
47+
48+
@Override
49+
public double getPriority() {
50+
return priority;
51+
}
52+
53+
@Override
54+
public void setPriority(double priority) {
55+
this.priority = priority;
56+
}
57+
58+
@Override
59+
public <PT extends IObjectScijavaAdapter> List<PluginInfo<PT>> getAdapters(
60+
Class<PT> adapterClass)
61+
{
62+
return pluginService().getPluginsOfType(adapterClass);
63+
}
64+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
package org.scijava.persist;
3+
4+
import com.google.gson.JsonDeserializer;
5+
import com.google.gson.JsonSerializer;
6+
7+
public interface IClassAdapter<T> extends IObjectScijavaAdapter,
8+
JsonSerializer<T>, JsonDeserializer<T>
9+
{
10+
11+
Class<? extends T> getAdapterClass();
12+
13+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
package org.scijava.persist;
3+
4+
import com.google.gson.JsonDeserializer;
5+
import com.google.gson.JsonElement;
6+
import com.google.gson.JsonSerializer;
7+
import com.google.gson.JsonSerializationContext;
8+
import com.google.gson.JsonDeserializationContext;
9+
import com.google.gson.JsonParseException;
10+
import com.google.gson.JsonIOException;
11+
12+
import java.lang.reflect.Type;
13+
14+
public interface IClassRuntimeAdapter<B, T extends B> extends
15+
IObjectScijavaAdapter, JsonSerializer<T>, JsonDeserializer<T>
16+
{
17+
18+
Class<? extends B> getBaseClass();
19+
20+
Class<? extends T> getRunTimeClass();
21+
22+
default boolean useCustomAdapter() {
23+
return false;
24+
}
25+
26+
@Override
27+
default T deserialize(JsonElement json, Type typeOfT,
28+
JsonDeserializationContext context) throws JsonParseException
29+
{
30+
throw new JsonParseException("Default deserializer for class " +
31+
getBaseClass() + " (" + getRunTimeClass() +
32+
") should not be used, return false in method useCustomAdapter instead");
33+
}
34+
35+
@Override
36+
default JsonElement serialize(T src, Type typeOfSrc,
37+
JsonSerializationContext context)
38+
{
39+
throw new JsonIOException("Default serializer for class " + getBaseClass() +
40+
" (" + getRunTimeClass() +
41+
") should not be used, should not be used, return false in method useCustomAdapter instead");
42+
}
43+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
package org.scijava.persist;
3+
4+
import org.scijava.plugin.SciJavaPlugin;
5+
6+
/**
7+
* Top level class for plugins which can serialize object using gson and the
8+
* scijava context. The scijava context may provide custom adapters
9+
* {@link IClassAdapter} and also runtime adapters, see
10+
* {@link IClassRuntimeAdapter}) auto-discovered via scijava plugin
11+
* extensibility mechanism.
12+
*
13+
* @author Nicolas Chiaruttini, EPFL, 2021
14+
*/
15+
16+
public interface IObjectScijavaAdapter extends SciJavaPlugin {}

0 commit comments

Comments
 (0)