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
@@ -0,0 +1,5 @@
1
+ class Semantizer
2
+ require 'virtual_assembly/semantizer/semantic_object'
3
+ require 'virtual_assembly/semantizer/semantic_property'
4
+ require 'virtual_assembly/semantizer/hash_serializer'
5
+ 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: []