├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── pom.xml
└── src
├── main
└── java
│ └── ioinformarics
│ └── oss
│ └── jackson
│ └── module
│ └── jsonld
│ ├── BeanJsonldResource.java
│ ├── HydraCollection.java
│ ├── HydraCollectionBuilder.java
│ ├── JsonldContextFactory.java
│ ├── JsonldGraph.java
│ ├── JsonldGraphBuilder.java
│ ├── JsonldModule.java
│ ├── JsonldResource.java
│ ├── JsonldResourceBuilder.java
│ ├── MapJsonldResource.java
│ ├── annotation
│ ├── JsonldId.java
│ ├── JsonldLink.java
│ ├── JsonldLinks.java
│ ├── JsonldNamespace.java
│ ├── JsonldProperty.java
│ ├── JsonldResource.java
│ ├── JsonldType.java
│ └── JsonldTypeFromJavaClass.java
│ ├── internal
│ ├── AnnotationConstants.java
│ ├── JsonldBeanDeserializerModifier.java
│ ├── JsonldPropertyNamingStrategy.java
│ ├── JsonldResourceSerializer.java
│ └── JsonldResourceSerializerModifier.java
│ └── util
│ ├── AnnotationsUtils.java
│ ├── JsonUtils.java
│ └── JsonldResourceUtils.java
└── test
└── java
└── ioinformarics
└── oss
└── jackson
└── module
└── jsonld
├── JsonldContextFactoryTest.java
├── JsonldModuleTest.java
└── testobjects
├── Child.java
├── Parent.java
└── internal
└── TestObject.java
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | pom.xml.tag
3 | pom.xml.releaseBackup
4 | pom.xml.versionsBackup
5 | pom.xml.next
6 | release.properties
7 | .idea
8 | jackson-jsonld.iml
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk:
3 | - oraclejdk8
4 | script:
5 | - mvn clean test
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 IO Informatics Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # jackson-jsonld [](http://www.opensource.org/licenses/MIT) [](https://travis-ci.org/io-informatics/jackson-jsonld) [](https://gitter.im/io-informatics/jackson-jsonld?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
2 |
3 | JSON-LD Module for Jackson
4 |
5 | ## Install it
6 | If you use maven, just add the dependency to your pom.xml
7 | ```xml
8 |
9 | com.io-informatics.oss
10 | jackson-jsonld
11 | 0.0.5
12 |
13 | ```
14 |
15 | ## Use it
16 | The first step is to register the module with jackson.
17 | ```java
18 | // this configure the JsonldModule with an empty default context.
19 | objectMapper.registerModule(new JsonldModule());
20 | ```
21 | If you want to provide a default JSON-LD context for your application check the other constructors of [JsonldModule](https://github.com/io-informatics/jackson-jsonld/blob/master/src/main/java/ioinformarics/oss/jackson/module/jsonld/JsonldModule.java#L25)
22 |
23 |
24 | Next, we can have annotated java beans which can be serialized using Jsonld. For instance:
25 |
26 | ```java
27 | @JsonldType("http://schema.org/Person")
28 | public class Person {
29 | @JsonldId
30 | public String id;
31 | @JsonldProperty("http://schema.org/name")
32 | public String name;
33 | @JsonldProperty("http://schema.org/jobTitle")
34 | public String jobtitle;
35 | @JsonldProperty("http://schema.org/url")
36 | public String url;
37 | }
38 | ```
39 |
40 | Instances of Person can we wrapped inside a JsonldResource or JsonldGraph/HydraCollection. To do this you can use the builders that the library provides:
41 |
42 | ```java
43 | Person alex = new Person();
44 | alex.id = "mailto:me@alexdeleon.name";
45 | alex.name = "Alex De Leon";
46 | alex.jobtitle = "Software Developer";
47 | alex.url = "http://alexdeleon.name";
48 |
49 | objectMapper.writer().writeValue(System.out, JsonldResource.Builder.create().build(alex));
50 | ```
51 | The above will generate the following JSON-LD representation:
52 |
53 | ```json
54 | {
55 | "@context": {
56 | "name": "http://schema.org/name",
57 | "jobtitle": "http://schema.org/jobTitle",
58 | "url": "http://schema.org/url"
59 | },
60 | "@type": "http://schema.org/Person",
61 | "name": "Alex De Leon",
62 | "jobtitle": "Software Developer",
63 | "url": "http://alexdeleon.name",
64 | "@id": "mailto:me@alexdeleon.name"
65 | }
66 | ```
67 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | com.io-informatics.oss
6 | jackson-jsonld
7 | 0.1.2-SNAPSHOT
8 | jackson-jsonld
9 | JSON-LD Module for Jackson
10 | https://github.com/io-informatics/jackson-jsonld
11 |
12 |
13 | scm:git:git@github.com:io-informatics/jackson-jsonld.git
14 | scm:git:git@github.com:io-informatics/jackson-jsonld.git
15 | scm:git:git@github.com:io-informatics/jackson-jsonld.git
16 | HEAD
17 |
18 |
19 |
20 |
21 | Alexander De Leon
22 | adeleon@io-informatics.com
23 | Europe/Madrid
24 |
25 | committer
26 |
27 |
28 |
29 |
30 |
31 | 2.4.4
32 | 2.4.4
33 | 0.5.1
34 |
35 |
36 |
37 |
38 | com.fasterxml.jackson.core
39 | jackson-annotations
40 | ${version.jackson.annotations}
41 |
42 |
43 | com.fasterxml.jackson.core
44 | jackson-core
45 | ${version.jackson.core}
46 |
47 |
48 | com.fasterxml.jackson.core
49 | jackson-databind
50 | ${version.jackson.core}
51 |
52 |
53 | com.github.jsonld-java
54 | jsonld-java
55 | ${version.jsonld.java}
56 |
57 |
58 | org.apache.commons
59 | commons-lang3
60 | 3.3.2
61 |
62 |
63 | io.github.lukehutch
64 | fast-classpath-scanner
65 | 1.99.0
66 |
67 |
68 | junit
69 | junit
70 | 4.11
71 | test
72 |
73 |
74 | org.hamcrest
75 | hamcrest-junit
76 | 2.0.0.0
77 | test
78 |
79 |
80 |
81 |
82 |
83 |
84 | org.apache.maven.plugins
85 | maven-compiler-plugin
86 | 3.1
87 |
88 | 1.8
89 | 1.8
90 |
91 |
92 |
93 | org.sonatype.plugins
94 | nexus-staging-maven-plugin
95 | 1.6.5
96 | true
97 |
98 | sonatype-releases
99 | https://oss.sonatype.org/
100 | true
101 |
102 |
103 |
104 | org.apache.maven.plugins
105 | maven-release-plugin
106 | 2.4.1
107 |
108 |
109 | org.apache.maven.scm
110 | maven-scm-provider-gitexe
111 | 1.9
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 | sonatype-releases
121 | Sonatype Nexus releases repository
122 | https://oss.sonatype.org/content/repositories/releases
123 |
124 |
125 | sonatype
126 | Sonatype Nexus snapshot repository
127 | https://oss.sonatype.org/content/repositories/snapshots
128 |
129 |
130 |
131 |
132 |
133 | sonatype
134 | Sonatype Nexus snapshot repository
135 | https://oss.sonatype.org/content/repositories/snapshots
136 | true
137 |
138 |
139 | sonatype-releases
140 | Sonatype Nexus releases repository
141 | https://oss.sonatype.org/content/repositories/releases
142 | false
143 |
144 |
145 |
146 |
147 | Travis CI
148 | https://travis-ci.org/io-informatics/jackson-jsonld
149 |
150 |
151 |
152 | https://github.com/io-informatics/jackson-jsonld/issues
153 | GitHub Issues
154 |
155 |
156 |
157 |
158 | MIT License
159 | http://www.opensource.org/licenses/mit-license.php
160 | repo
161 |
162 |
163 |
164 |
165 |
166 | release-sign-artifacts
167 |
168 |
169 | performRelease
170 | true
171 |
172 |
173 |
174 |
175 |
176 | org.apache.maven.plugins
177 | maven-gpg-plugin
178 |
179 |
180 | sign-artifacts
181 | verify
182 |
183 | sign
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
--------------------------------------------------------------------------------
/src/main/java/ioinformarics/oss/jackson/module/jsonld/BeanJsonldResource.java:
--------------------------------------------------------------------------------
1 | package ioinformarics.oss.jackson.module.jsonld;
2 |
3 | import com.fasterxml.jackson.annotation.JsonInclude;
4 | import com.fasterxml.jackson.annotation.JsonProperty;
5 | import com.fasterxml.jackson.annotation.JsonPropertyOrder;
6 | import com.fasterxml.jackson.annotation.JsonUnwrapped;
7 | import com.fasterxml.jackson.databind.JsonNode;
8 |
9 | /**
10 | * @author Alexander De Leon
11 | */
12 | @JsonPropertyOrder({"@context", "@type", "@id"})
13 | public class BeanJsonldResource implements JsonldResource{
14 |
15 | @JsonUnwrapped
16 | @JsonInclude(JsonInclude.Include.NON_NULL)
17 | public final Object scopedObj;
18 |
19 | @JsonProperty("@context")
20 | @JsonInclude(JsonInclude.Include.NON_NULL)
21 | public final JsonNode context;
22 |
23 | @JsonProperty("@type")
24 | @JsonInclude(JsonInclude.Include.NON_NULL)
25 | public final String type;
26 |
27 | @JsonProperty("@id")
28 | @JsonInclude(JsonInclude.Include.NON_NULL)
29 | public final String id;
30 |
31 |
32 | BeanJsonldResource(Object scopedObj, JsonNode context, String type, String id) {
33 | this.scopedObj = scopedObj;
34 | this.context = context;
35 | this.type = type;
36 | this.id = id;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/ioinformarics/oss/jackson/module/jsonld/HydraCollection.java:
--------------------------------------------------------------------------------
1 | package ioinformarics.oss.jackson.module.jsonld;
2 |
3 | import com.fasterxml.jackson.annotation.JsonInclude;
4 | import com.fasterxml.jackson.databind.JsonNode;
5 | import ioinformarics.oss.jackson.module.jsonld.annotation.JsonldProperty;
6 |
7 | /**
8 | * @author Alexander De Leon
9 | */
10 | public class HydraCollection extends BeanJsonldResource {
11 |
12 | HydraCollection(Iterable> graph, JsonNode context, String type, String id) {
13 | super(new CollectionContainer(graph), context, type, id);
14 | }
15 |
16 | HydraCollection(Iterable> graph,
17 | JsonNode context,
18 | String type,
19 | String id,
20 | Long totalItems,
21 | Integer itemsPerPage,
22 | String firstPage,
23 | String nextPage,
24 | String previousPage,
25 | String lastPage) {
26 | super(new CollectionContainer(graph, totalItems, itemsPerPage, firstPage, nextPage, previousPage, lastPage), context, type, id);
27 | }
28 |
29 | static class CollectionContainer {
30 | @JsonldProperty("hydra:member")
31 | @JsonInclude(JsonInclude.Include.NON_NULL)
32 | public final Iterable> member;
33 |
34 | @JsonldProperty("hydra:totalItems")
35 | @JsonInclude(JsonInclude.Include.NON_NULL)
36 | public final Long totalItems;
37 |
38 | @JsonldProperty("hydra:itemsPerPage")
39 | @JsonInclude(JsonInclude.Include.NON_NULL)
40 | public final Integer itemsPerPage;
41 |
42 | @JsonldProperty("hydra:firstPage")
43 | @JsonInclude(JsonInclude.Include.NON_NULL)
44 | public final String firstPage;
45 |
46 | @JsonldProperty("hydra:nextPage")
47 | @JsonInclude(JsonInclude.Include.NON_NULL)
48 | public final String nextPage;
49 |
50 | @JsonldProperty("hydra:previousPage")
51 | @JsonInclude(JsonInclude.Include.NON_NULL)
52 | public final String previousPage;
53 |
54 | @JsonldProperty("hydra:lastPage")
55 | @JsonInclude(JsonInclude.Include.NON_NULL)
56 | public final String lastPage;
57 |
58 | CollectionContainer(Iterable> member) {
59 | this(member, null,null,null,null,null,null);
60 | }
61 |
62 | public CollectionContainer(Iterable> member, Long totalItems, Integer itemsPerPage, String firstPage, String nextPage, String previousPage, String lastPage) {
63 | this.member = member;
64 | this.totalItems = totalItems;
65 | this.itemsPerPage = itemsPerPage;
66 | this.firstPage = firstPage;
67 | this.nextPage = nextPage;
68 | this.previousPage = previousPage;
69 | this.lastPage = lastPage;
70 | }
71 | }
72 |
73 | public interface Builder {
74 | static HydraCollectionBuilder create() {
75 | return new HydraCollectionBuilder();
76 | }
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/java/ioinformarics/oss/jackson/module/jsonld/HydraCollectionBuilder.java:
--------------------------------------------------------------------------------
1 | package ioinformarics.oss.jackson.module.jsonld;
2 |
3 | import com.fasterxml.jackson.annotation.JsonInclude;
4 | import com.fasterxml.jackson.databind.JsonNode;
5 | import com.fasterxml.jackson.databind.node.JsonNodeFactory;
6 | import com.fasterxml.jackson.databind.node.ObjectNode;
7 | import ioinformarics.oss.jackson.module.jsonld.annotation.JsonldProperty;
8 |
9 | import java.util.Optional;
10 |
11 | /**
12 | * @author Alexander De Leon
13 | */
14 | public class HydraCollectionBuilder extends JsonldGraphBuilder {
15 |
16 | private Long totalItems;
17 | private Integer itemsPerPage;
18 | private String firstPage;
19 | private String nextPage;
20 | private String previousPage;
21 | private String lastPage;
22 | private boolean isPaged = false;
23 |
24 |
25 | public HydraCollectionBuilder totalItems(Long totalItems) {
26 | this.totalItems = totalItems;
27 | isPaged = true;
28 | return this;
29 | }
30 |
31 | public HydraCollectionBuilder itemsPerPage(Integer itemsPerPage) {
32 | this.itemsPerPage = itemsPerPage;
33 | isPaged = true;
34 | return this;
35 | }
36 |
37 | public HydraCollectionBuilder firstPage(String firstPage) {
38 | this.firstPage = firstPage;
39 | isPaged = true;
40 | return this;
41 | }
42 |
43 | public HydraCollectionBuilder nextPage(String nextPage) {
44 | this.nextPage = nextPage;
45 | isPaged = true;
46 | return this;
47 | }
48 |
49 | public HydraCollectionBuilder previousPage(String previousPage) {
50 | this.previousPage = previousPage;
51 | isPaged = true;
52 | return this;
53 | }
54 |
55 | public HydraCollectionBuilder lastPage(String lastPage) {
56 | this.lastPage = lastPage;
57 | isPaged = true;
58 | return this;
59 | }
60 |
61 | public JsonldResource build(Iterable elements) {
62 | return new HydraCollection(elements, buildContext(elements).orElse(null),
63 | isPaged? "hydra:PagedCollection": "hydra:Collection", graphId, totalItems, itemsPerPage, firstPage, nextPage, previousPage, lastPage);
64 | }
65 |
66 | protected Optional buildContext(Iterable elements) {
67 | Optional hydraContext = JsonldContextFactory.fromAnnotations(HydraCollection.CollectionContainer.class);
68 | Optional mergedContext = hydraContext.map(it -> (ObjectNode)it.setAll(JsonldContextFactory.fromAnnotations(elements).orElse(emptyNode())));
69 | return JsonldContextFactory.multiContext(Optional.ofNullable(context), mergedContext);
70 | }
71 |
72 | private ObjectNode emptyNode() {
73 | return JsonNodeFactory.withExactBigDecimals(true).objectNode();
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/ioinformarics/oss/jackson/module/jsonld/JsonldContextFactory.java:
--------------------------------------------------------------------------------
1 | package ioinformarics.oss.jackson.module.jsonld;
2 |
3 | import com.fasterxml.jackson.databind.JsonNode;
4 | import com.fasterxml.jackson.databind.node.ArrayNode;
5 | import com.fasterxml.jackson.databind.node.JsonNodeFactory;
6 | import com.fasterxml.jackson.databind.node.ObjectNode;
7 | import com.fasterxml.jackson.databind.node.TextNode;
8 | import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
9 | import ioinformarics.oss.jackson.module.jsonld.annotation.*;
10 | import ioinformarics.oss.jackson.module.jsonld.util.AnnotationsUtils;
11 | import ioinformarics.oss.jackson.module.jsonld.util.JsonUtils;
12 | import ioinformarics.oss.jackson.module.jsonld.util.JsonldResourceUtils;
13 | import org.apache.commons.lang3.ClassUtils;
14 | import java.lang.reflect.Field;
15 | import java.lang.reflect.Modifier;
16 | import java.lang.reflect.ParameterizedType;
17 | import java.lang.reflect.Type;
18 | import java.util.*;
19 | import java.util.stream.Stream;
20 |
21 | /**
22 | * @author Alexander De Leon
23 | */
24 | public class JsonldContextFactory {
25 |
26 | public static ObjectNode fromPackage(String packageName) {
27 | ObjectNode generatedContext = JsonNodeFactory.withExactBigDecimals(true).objectNode();
28 | FastClasspathScanner scanner = new FastClasspathScanner(packageName);
29 | scanner.matchAllStandardClasses((clazz) -> {
30 | if(!Modifier.isAbstract(clazz.getModifiers()) && AnnotationsUtils.isAnnotationPresent(clazz, JsonldTypeFromJavaClass.class)) {
31 | Optional type = JsonldResourceUtils.dynamicTypeLookup(clazz);
32 | type.ifPresent(t ->generatedContext.set(clazz.getSimpleName(), TextNode.valueOf(t)));
33 | }
34 | if(AnnotationsUtils.isAnnotationPresent(clazz, ioinformarics.oss.jackson.module.jsonld.annotation.JsonldResource.class)) {
35 | Optional resourceContext = fromAnnotations(clazz);
36 | resourceContext.ifPresent((context) -> JsonUtils.merge(generatedContext, context));
37 | }
38 | });
39 | scanner.scan();
40 | return (ObjectNode) JsonNodeFactory.withExactBigDecimals(true).objectNode().set("@context", generatedContext);
41 | }
42 |
43 | public static Optional fromAnnotations(Object instance) {
44 | return fromAnnotations(instance.getClass());
45 | }
46 |
47 | public static Optional fromAnnotations(Iterable> instances) {
48 | ObjectNode mergedContext = JsonNodeFactory.withExactBigDecimals(true).objectNode();
49 | instances.forEach(e -> fromAnnotations(e).map(mergedContext::setAll));
50 | return mergedContext.size() != 0 ? Optional.of(mergedContext) : Optional.empty();
51 | }
52 |
53 | public static Optional fromAnnotations(Class> objType) {
54 | ObjectNode generatedContext = JsonNodeFactory.withExactBigDecimals(true).objectNode();
55 | generateNamespaces(objType).forEach((name, uri) -> generatedContext.set(name, new TextNode(uri)));
56 | //TODO: This is bad...it does not consider other Jackson annotations. Need to use a AnnotationIntrospector?
57 | final Map fieldContexts = generateContextsForFields(objType);
58 | fieldContexts.forEach(generatedContext::set);
59 | //add links
60 | JsonldLink[] links = objType.getAnnotationsByType(JsonldLink.class);
61 | if (links != null) {
62 | for (int i = 0; i < links.length; i++) {
63 | com.fasterxml.jackson.databind.node.ObjectNode linkNode = JsonNodeFactory.withExactBigDecimals(true)
64 | .objectNode();
65 | linkNode.set("@id", new TextNode(links[i].rel()));
66 | linkNode.set("@type", new TextNode("@id"));
67 | generatedContext.set(links[i].name(), linkNode);
68 | }
69 | }
70 | //Return absent optional if context is empty
71 | return generatedContext.size() != 0 ? Optional.of(generatedContext) : Optional.empty();
72 | }
73 |
74 | private static Map generateContextsForFields(Class> objType) {
75 | return generateContextsForFields(objType, new ArrayList<>());
76 | }
77 |
78 | private static Map generateContextsForFields(Class> objType, List> ignoreTypes) {
79 | final Map contexts = new HashMap<>();
80 | Class> currentClass = objType;
81 | Optional namespace = Optional.ofNullable(currentClass.getAnnotation(JsonldNamespace.class));
82 | while (currentClass != null && !currentClass.equals(Object.class)) {
83 | final Field[] fields = currentClass.getDeclaredFields();
84 | for (Field f : fields) {
85 | if(f.isAnnotationPresent(JsonldId.class) || f.getName().equals("this$0")) {
86 | continue;
87 | }
88 | final JsonldProperty jsonldProperty = f.getAnnotation(JsonldProperty.class);
89 | Optional propertyId = Optional.empty();
90 | // Most concrete field overrides any field with the same name defined higher up the hierarchy
91 | if (jsonldProperty != null && !contexts.containsKey(f.getName())) {
92 | propertyId = Optional.of(jsonldProperty.value());
93 | }
94 | else if(jsonldProperty == null && namespace.map(JsonldNamespace::applyToProperties).orElse(false)) {
95 | propertyId = Optional.of(namespace.get().name() + ":" + f.getName());
96 | }
97 | propertyId.ifPresent((id) -> {
98 | if(isRelation(f)) {
99 | ObjectNode node = JsonNodeFactory.withExactBigDecimals(true).objectNode();
100 | node.set("@id", TextNode.valueOf(id));
101 | node.set("@type", TextNode.valueOf("@id"));
102 | contexts.put(f.getName(), node);
103 | }
104 | else {
105 | contexts.put(f.getName(), TextNode.valueOf(id));
106 | }
107 | });
108 | }
109 | currentClass = currentClass.getSuperclass();
110 | if(!namespace.isPresent()) {
111 | namespace = Optional.ofNullable(currentClass.getAnnotation(JsonldNamespace.class));
112 | }
113 | }
114 | return contexts;
115 | }
116 |
117 | private static Class> relationType(Field field) {
118 | Class> type = field.getType();
119 | if(Collection.class.isAssignableFrom(type)) {
120 | ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
121 | Type t = parameterizedType.getActualTypeArguments()[0];
122 | if(Class.class.isAssignableFrom(t.getClass())) {
123 | type = (Class>) t;
124 | }
125 | else if(ParameterizedType.class.isAssignableFrom(t.getClass())) {
126 | type = (Class>)((ParameterizedType) t).getRawType();
127 | }
128 | }
129 | if(type.isArray()) {
130 | type = type.getComponentType();
131 | }
132 | return type;
133 | }
134 |
135 | private static boolean isRelation(Field field) {
136 | Class> type = relationType(field);
137 | return Stream.concat(Stream.of(type),
138 | Stream.concat(ClassUtils.getAllSuperclasses(type).stream(), ClassUtils.getAllInterfaces(type).stream()))
139 | .flatMap(currentClass -> Stream.concat(
140 | Stream.of(currentClass.getDeclaredFields()),
141 | Stream.of(currentClass.getDeclaredMethods())
142 | ))
143 | .anyMatch(p -> p.getAnnotation(JsonldId.class) != null);
144 | }
145 |
146 | private static Map generateNamespaces(Class> objType) {
147 | JsonldNamespace[] namespaceAnnotations = objType.getAnnotationsByType(JsonldNamespace.class);
148 | Map namespaces = new HashMap<>(namespaceAnnotations.length);
149 | Arrays.asList(namespaceAnnotations).forEach((ns) -> namespaces.put(ns.name(), ns.uri()));
150 | return namespaces;
151 | }
152 |
153 |
154 | public static Optional multiContext(Optional externalContext,
155 | Optional internalContext) {
156 | if (internalContext.isPresent()) {
157 | return externalContext.isPresent() ?
158 | Optional.of((JsonNode) buildMultiContext(externalContext.get(), internalContext.get())) :
159 | internalContext.map(it -> (JsonNode) it);
160 | }
161 | return externalContext.map(TextNode::valueOf);
162 | }
163 |
164 | private static ArrayNode buildMultiContext(String context, JsonNode generatedContext) {
165 | return JsonNodeFactory.withExactBigDecimals(true).arrayNode().add(context).add(generatedContext);
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/src/main/java/ioinformarics/oss/jackson/module/jsonld/JsonldGraph.java:
--------------------------------------------------------------------------------
1 | package ioinformarics.oss.jackson.module.jsonld;
2 |
3 | import com.fasterxml.jackson.annotation.JsonInclude;
4 | import com.fasterxml.jackson.annotation.JsonProperty;
5 | import com.fasterxml.jackson.databind.JsonNode;
6 |
7 | /**
8 | * @author Alexander De Leon
9 | */
10 | public class JsonldGraph extends BeanJsonldResource {
11 |
12 |
13 | JsonldGraph(Iterable> graph, JsonNode context, String type, String id) {
14 | super(new JsonldGraphContainer(graph), context, type, id);
15 | }
16 |
17 |
18 | static class JsonldGraphContainer {
19 | @JsonProperty("@graph")
20 | @JsonInclude(JsonInclude.Include.NON_NULL)
21 | public final Iterable> graph;
22 |
23 | JsonldGraphContainer(Iterable> graph) {
24 | this.graph = graph;
25 | }
26 | }
27 |
28 | public interface Builder {
29 | static JsonldGraphBuilder create() {
30 | return new JsonldGraphBuilder();
31 | }
32 | }
33 | }
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/main/java/ioinformarics/oss/jackson/module/jsonld/JsonldGraphBuilder.java:
--------------------------------------------------------------------------------
1 | package ioinformarics.oss.jackson.module.jsonld;
2 |
3 | import com.fasterxml.jackson.databind.JsonNode;
4 | import com.fasterxml.jackson.databind.node.TextNode;
5 |
6 | import java.util.ArrayList;
7 | import java.util.Arrays;
8 | import java.util.Optional;
9 | import java.util.function.Function;
10 |
11 | /**
12 | * @author Alexander De Leon
13 | */
14 | public class JsonldGraphBuilder {
15 |
16 | protected String context;
17 | protected String graphType;
18 | protected String graphId;
19 | protected JsonldResourceBuilder resourceBuilder;
20 | protected Function typeSupplier;
21 |
22 | JsonldGraphBuilder() {
23 | resourceBuilder = new JsonldResourceBuilder();
24 | }
25 |
26 | public JsonldGraphBuilder context(String context){
27 | this.context = context;
28 | return this;
29 | }
30 |
31 | public JsonldGraphBuilder type(String type){
32 | this.graphType = type;
33 | return this;
34 | }
35 |
36 | public JsonldGraphBuilder id(String id){
37 | this.graphId = id;
38 | return this;
39 | }
40 |
41 | public JsonldGraphBuilder elementId(Function idSupplier){
42 | this.resourceBuilder.id(idSupplier);
43 | return this;
44 | }
45 |
46 | public JsonldGraphBuilder elementType(Function typeSupplier){
47 | this.typeSupplier = typeSupplier;
48 | return this;
49 | }
50 |
51 | public JsonldResource build(T ... elements) {
52 | return build(Arrays.asList(elements));
53 | }
54 |
55 | public JsonldResource build(Iterable elements) {
56 | return new JsonldGraph(elements, Optional.ofNullable(context).map(c -> TextNode.valueOf(c)).orElse(null), graphType, graphId);
57 |
58 | }
59 |
60 | protected String getType(T e) {
61 | return typeSupplier.apply(e);
62 | }
63 |
64 |
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/ioinformarics/oss/jackson/module/jsonld/JsonldModule.java:
--------------------------------------------------------------------------------
1 | package ioinformarics.oss.jackson.module.jsonld;
2 |
3 | import com.fasterxml.jackson.databind.module.SimpleModule;
4 | import ioinformarics.oss.jackson.module.jsonld.internal.JsonldBeanDeserializerModifier;
5 | import ioinformarics.oss.jackson.module.jsonld.internal.JsonldPropertyNamingStrategy;
6 | import ioinformarics.oss.jackson.module.jsonld.internal.JsonldResourceSerializerModifier;
7 | import jdk.nashorn.internal.ir.ObjectNode;
8 |
9 | import java.util.Collections;
10 | import java.util.HashMap;
11 | import java.util.Map;
12 | import java.util.function.Supplier;
13 |
14 | /**
15 | * @author Alexander De Leon
16 | */
17 | public class JsonldModule extends SimpleModule {
18 |
19 | /**
20 | * Create a JsonldModule configured with a function which supplies the @context structure of your application.
21 | * This constructor is useful if you want to construct your context dynamically. If the context is static is better to use the other constructors of this class.
22 | *
23 | * @param contextSupplier a function from () to Object which supplies the default Jsonld context of your application.
24 | */
25 | public JsonldModule(Supplier