virtual_assembly-semantizer 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
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: []
|