virtual_assembly-semantizer 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cbd44cbccb6f557aebdb7ef2cb5ed9119ae53839dba26f0a9540794a4fa447a5
|
4
|
+
data.tar.gz: 973105f42f81b44ae526b34c822c05898bcd29d8b5a94edbf99b189c4381970e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d032ce8d8eee24379cb6babc939ffdb6243187f7347f7f2d151c742acb5f62cdeb8e0d5d07216131aaced9d518edc26b854e83bc36da11283de011f6c57e349d
|
7
|
+
data.tar.gz: 1c55b2707feb65c622a080c27ec6af6d26cf9abc9c9fe556dfd1a4b4c32ebaf2b6197c730cfadfcafaa5b04958919e0deae40c96b53d17222b6aa97af1f5d6f4
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# Copyright © 2023 Maxime Lecoq, <maxime@lecoqlibre.fr>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
4
|
+
# and associated documentation files (the “Software”), to deal in the Software without
|
5
|
+
# restriction, including without limitation the rights to use, copy, modify, merge, publish,
|
6
|
+
# distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
|
7
|
+
# Software is furnished to do so, subject to the following conditions:
|
8
|
+
#
|
9
|
+
# The above copyright notice and this permission notice shall be included in all copies or
|
10
|
+
# substantial portions of the Software.
|
11
|
+
|
12
|
+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
13
|
+
# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
14
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
15
|
+
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
16
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
17
|
+
|
18
|
+
# The HashSerializer turns all the semantic properties of a SemanticObject into a Hash.
|
19
|
+
#
|
20
|
+
# Lets consider the following SemanticObject with a single semantic property like:
|
21
|
+
# - name: "http://xmlns.com/foaf/0.1/name"
|
22
|
+
# - value: "John"
|
23
|
+
#
|
24
|
+
# The HashSerializer will return the following Hash:
|
25
|
+
# {"http://xmlns.com/foaf/0.1/name" => "John"}.
|
26
|
+
class Semantizer::HashSerializer
|
27
|
+
|
28
|
+
# This is the main method to begin the serialization.
|
29
|
+
#
|
30
|
+
# The subject should be a SemanticObject.
|
31
|
+
def process(subject)
|
32
|
+
result = {}
|
33
|
+
|
34
|
+
# We iterate over all the semantic properties of the subject.
|
35
|
+
subject.semanticProperties.each do |property|
|
36
|
+
name = property.name
|
37
|
+
value = property.value
|
38
|
+
|
39
|
+
if (value == nil)
|
40
|
+
next
|
41
|
+
end
|
42
|
+
|
43
|
+
# In case the property is a primitive, we simply get its value.
|
44
|
+
if ([ String, Integer, Float, TrueClass, FalseClass ].include?(value.class))
|
45
|
+
result[name] = value
|
46
|
+
|
47
|
+
# In case the property is a SemanticObject, we get its semanticId
|
48
|
+
# or we process it if it is a blank node.
|
49
|
+
elsif (value.is_a? SemanticObject)
|
50
|
+
if (value.isBlankNode?)
|
51
|
+
result[name] = process(value)
|
52
|
+
else
|
53
|
+
result[name] = value.semanticId
|
54
|
+
end
|
55
|
+
|
56
|
+
# In case the property is an Array, we export each item.
|
57
|
+
elsif (value.class == Array)
|
58
|
+
result[name] = exportCollection(value)
|
59
|
+
|
60
|
+
else
|
61
|
+
raise "The type of the property '" + name + "' is '" + value.class.to_s + "' but a primitive, a SemanticObject or an Array is required."
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
return result;
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
# Serialize a collection of values.
|
71
|
+
def exportCollection(values)
|
72
|
+
collection = []
|
73
|
+
|
74
|
+
if (!values.empty?)
|
75
|
+
type = values.at(0).class
|
76
|
+
|
77
|
+
# If the collection contains only primitives, we simply return it.
|
78
|
+
if ([ String, Integer, Float, TrueClass, FalseClass ].include?(type))
|
79
|
+
collection = values
|
80
|
+
|
81
|
+
# In case the collection contains SemanticObject we have to process
|
82
|
+
# the blank nodes or return the semantic id.
|
83
|
+
elsif type == SemanticObject
|
84
|
+
values.each do |item|
|
85
|
+
if (item.isBlankNode?)
|
86
|
+
collection.push(process(item))
|
87
|
+
else
|
88
|
+
collection.push(item.semanticId)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
else
|
92
|
+
raise "Elements of the collection are not primitive nor SemanticObject."
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
return collection;
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
# Copyright © 2023 Maxime Lecoq, <maxime@lecoqlibre.fr>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
4
|
+
# and associated documentation files (the “Software”), to deal in the Software without
|
5
|
+
# restriction, including without limitation the rights to use, copy, modify, merge, publish,
|
6
|
+
# distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
|
7
|
+
# Software is furnished to do so, subject to the following conditions:
|
8
|
+
#
|
9
|
+
# The above copyright notice and this permission notice shall be included in all copies or
|
10
|
+
# substantial portions of the Software.
|
11
|
+
|
12
|
+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
13
|
+
# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
14
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
15
|
+
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
16
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
17
|
+
|
18
|
+
require 'virtual_assembly/semantizer/semantic_property'
|
19
|
+
|
20
|
+
# The SemanticObject module is designed to add linked data
|
21
|
+
# to classical objects.
|
22
|
+
#
|
23
|
+
# A semanticObject holds semantic properties (SemanticProperty)
|
24
|
+
# that refers to linked data concepts.
|
25
|
+
#
|
26
|
+
# For example, a Person object including this module could register
|
27
|
+
# in its initializer method a semantic property for its name like:
|
28
|
+
# Person.registerSemanticProperty("http://xmlns.com/foaf/0.1/name") {self.name}
|
29
|
+
module Semantizer::SemanticObject
|
30
|
+
|
31
|
+
# The semantic ID implements the concept of linked data ID.
|
32
|
+
#
|
33
|
+
# This ID is an uri pointing to the location of the object
|
34
|
+
# on the web like "https://mywebsite/myobject" for instance.
|
35
|
+
#
|
36
|
+
# If a SemanticObject doesn't define its ID, it
|
37
|
+
# will be considered as a blank node.
|
38
|
+
#
|
39
|
+
# This should be a String or nil.
|
40
|
+
attr_accessor :semanticId
|
41
|
+
|
42
|
+
# The semantic type implements the concept of linked data type
|
43
|
+
# (also called class).
|
44
|
+
#
|
45
|
+
# This type is an uri pointing to the location of the linked
|
46
|
+
# data concept on the web like "http://xmlns.com/foaf/0.1/Person"
|
47
|
+
# for instance.
|
48
|
+
#
|
49
|
+
# This should be a String or nil.
|
50
|
+
attr_accessor :semanticType
|
51
|
+
|
52
|
+
# This Array stores the semantic properties of the object.
|
53
|
+
# To append a SemanticProperty, use the dedicated
|
54
|
+
# registerSemanticProperty method. You should pass the value
|
55
|
+
# of the property as a block (callback) like so:
|
56
|
+
# registerSemanticProperty("http://xmlns.com/foaf/0.1/name") {self.name}.
|
57
|
+
attr_reader :semanticProperties
|
58
|
+
|
59
|
+
# If the semanticId is nil, the object will be treated as a blank node.
|
60
|
+
def initialize(semanticId = nil, semanticType = nil)
|
61
|
+
@semanticId = semanticId
|
62
|
+
@semanticType = semanticType
|
63
|
+
@semanticProperties = Array.new
|
64
|
+
|
65
|
+
# This Hash allows us to find a property using its name.
|
66
|
+
#
|
67
|
+
# Hash<String, Integer>
|
68
|
+
#
|
69
|
+
# The key store the name of a property (String).
|
70
|
+
# The value store the index of the property in the
|
71
|
+
# semanticProperties array (Integer).
|
72
|
+
@semanticPropertiesNameIndex = Hash.new
|
73
|
+
end
|
74
|
+
|
75
|
+
def hasSemanticProperty?(name)
|
76
|
+
return @semanticPropertiesNameIndex.include?(name)
|
77
|
+
end
|
78
|
+
|
79
|
+
def isBlankNode?
|
80
|
+
return @semanticId == nil || @semanticId == ""
|
81
|
+
end
|
82
|
+
|
83
|
+
# Given the name of the property, it returns the value
|
84
|
+
# associated to a property of this object.
|
85
|
+
def semanticPropertyValue(name)
|
86
|
+
index = @semanticPropertiesNameIndex.fetch(name, nil)
|
87
|
+
return index != nil ? @semanticProperties[index].value : nil;
|
88
|
+
end
|
89
|
+
|
90
|
+
# Use this method to append a semantic property to this object.
|
91
|
+
# The value of the property should be passed as a block so its
|
92
|
+
# value would be up to date when we will access it.
|
93
|
+
def registerSemanticProperty(name, &valueGetter)
|
94
|
+
createOrUpdateSemanticProperty(name, valueGetter)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Sets the semantic id of the object and registers the
|
98
|
+
# corresponding semantic property.
|
99
|
+
#
|
100
|
+
# The semantic ID implements the concept of linked data ID.
|
101
|
+
#
|
102
|
+
# This ID is an uri pointing to the location of the object
|
103
|
+
# on the web like "https://mywebsite/myobject" for instance.
|
104
|
+
#
|
105
|
+
# If a SemanticObject doesn't define its ID, it
|
106
|
+
# will be considered as a blank node.
|
107
|
+
#
|
108
|
+
# This should be a String or nil.
|
109
|
+
def semanticId=(uri)
|
110
|
+
@semanticId = uri
|
111
|
+
registerSemanticProperty("@id") {self.semanticId}
|
112
|
+
end
|
113
|
+
|
114
|
+
# Sets the semantic type of the object and registers the
|
115
|
+
# corresponding semantic property.
|
116
|
+
#
|
117
|
+
# The semantic type implements the concept of linked data type
|
118
|
+
# (also called class).
|
119
|
+
#
|
120
|
+
# This type is an uri pointing to the location of the linked
|
121
|
+
# data concept on the web like "http://xmlns.com/foaf/0.1/Person"
|
122
|
+
# for instance.
|
123
|
+
#
|
124
|
+
# This should be a String or nil.
|
125
|
+
def semanticType=(type)
|
126
|
+
@semanticType = type
|
127
|
+
registerSemanticProperty("@type") {self.semanticType}
|
128
|
+
end
|
129
|
+
|
130
|
+
# Serialize all the semantic properties of this object
|
131
|
+
# to an output format.
|
132
|
+
#
|
133
|
+
# You could use the HashSerializer to export as a Hash.
|
134
|
+
# This Hash should be then exported to JSON for instance.
|
135
|
+
def serialize(serializer)
|
136
|
+
return serializer.process(self)
|
137
|
+
end
|
138
|
+
|
139
|
+
protected
|
140
|
+
|
141
|
+
# If the semantic property already exist in this object, this
|
142
|
+
# method will simply update the valueGetter of the property.
|
143
|
+
#
|
144
|
+
# If this object does not holds the property, the new property
|
145
|
+
# will be added into the semanticProperties Array of this object.
|
146
|
+
def createOrUpdateSemanticProperty(name, valueGetter)
|
147
|
+
# Update
|
148
|
+
if (hasSemanticProperty?(name))
|
149
|
+
semanticProperty = findSemanticProperty(name)
|
150
|
+
if (semanticProperty != nil)
|
151
|
+
semanticProperty.valueGetter = valueGetter
|
152
|
+
end
|
153
|
+
|
154
|
+
# Create
|
155
|
+
else
|
156
|
+
@semanticProperties.push(Semantizer::SemanticProperty.new(name, &valueGetter))
|
157
|
+
index = @semanticProperties.count - 1
|
158
|
+
@semanticPropertiesNameIndex.store(name, index);
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# Given its name, returns the corresponding SemanticProperty
|
163
|
+
# stored by this object or nil if the property does not exist.
|
164
|
+
def findSemanticProperty(name)
|
165
|
+
begin
|
166
|
+
index = @semanticPropertiesNameIndex.fetch(name)
|
167
|
+
return @semanticProperties.at(index)
|
168
|
+
rescue
|
169
|
+
return nil
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Copyright © 2023 Maxime Lecoq, <maxime@lecoqlibre.fr>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
4
|
+
# and associated documentation files (the “Software”), to deal in the Software without
|
5
|
+
# restriction, including without limitation the rights to use, copy, modify, merge, publish,
|
6
|
+
# distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
|
7
|
+
# Software is furnished to do so, subject to the following conditions:
|
8
|
+
#
|
9
|
+
# The above copyright notice and this permission notice shall be included in all copies or
|
10
|
+
# substantial portions of the Software.
|
11
|
+
|
12
|
+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
13
|
+
# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
14
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
15
|
+
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
16
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
17
|
+
|
18
|
+
# The SemanticPropety class is designed to turn properties of
|
19
|
+
# objects into linked data.
|
20
|
+
#
|
21
|
+
# A SemanticProperty has a name and a corresponding value that
|
22
|
+
# can be fetched later (so its value would be up to date).
|
23
|
+
#
|
24
|
+
# This class is intented to be used through the SemanticObject
|
25
|
+
# class.
|
26
|
+
#
|
27
|
+
# For instance, we can tell that the name of a Person object refers
|
28
|
+
# to the linked data concept "name" from the FOAF project. The name
|
29
|
+
# of the property would be the uri of the FOAF:name property while the
|
30
|
+
# value would be the attribute reader of the name of the Person object.
|
31
|
+
#
|
32
|
+
# You should use a block to pass the value like so:
|
33
|
+
# SemanticProperty.new("http://xmlns.com/foaf/0.1/name") {self.name}
|
34
|
+
class Semantizer::SemanticProperty
|
35
|
+
|
36
|
+
# The name of the property. It generally points to an uri
|
37
|
+
# like "http://xmlns.com/foaf/0.1/name" or it is used to
|
38
|
+
# define a reserved linked data property like "@id".
|
39
|
+
#
|
40
|
+
# This should be a String.
|
41
|
+
attr_accessor :name
|
42
|
+
|
43
|
+
# The function to call when the value is requested.
|
44
|
+
#
|
45
|
+
# This should be a Proc passed as a Block.
|
46
|
+
attr_accessor :valueGetter
|
47
|
+
|
48
|
+
# @param name The name of the property, like
|
49
|
+
# "http://xmlns.com/foaf/0.1/name" or "@id" for instance.
|
50
|
+
#
|
51
|
+
# @param valueGetter A Proc used to retrieve the value of the
|
52
|
+
# property when requested.
|
53
|
+
def initialize(name, &valueGetter)
|
54
|
+
@name = name
|
55
|
+
@valueGetter = valueGetter
|
56
|
+
end
|
57
|
+
|
58
|
+
# Fetch and returns the value associated to this property.
|
59
|
+
def value
|
60
|
+
return @valueGetter.call
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
metadata
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: virtual_assembly-semantizer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Maxime Lecoq
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-01-05 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A library to add linked data to your models
|
14
|
+
email: maxime@lecoqlibre.fr
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/virtual_assembly/semantizer.rb
|
20
|
+
- lib/virtual_assembly/semantizer/hash_serializer.rb
|
21
|
+
- lib/virtual_assembly/semantizer/semantic_object.rb
|
22
|
+
- lib/virtual_assembly/semantizer/semantic_property.rb
|
23
|
+
homepage: https://github.com/assemblee-virtuelle/semantizer-ruby/
|
24
|
+
licenses:
|
25
|
+
- MIT
|
26
|
+
metadata: {}
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
requirements: []
|
42
|
+
rubygems_version: 3.3.25
|
43
|
+
signing_key:
|
44
|
+
specification_version: 4
|
45
|
+
summary: Semantizer
|
46
|
+
test_files: []
|