sdl-ng 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/sdl.rb +18 -7
- data/lib/sdl/base.rb +7 -6
- data/lib/sdl/base/fact.rb +7 -11
- data/lib/sdl/base/property.rb +22 -26
- data/lib/sdl/base/service.rb +8 -12
- data/lib/sdl/base/service_compendium.rb +97 -109
- data/lib/sdl/base/type.rb +62 -68
- data/lib/sdl/exporters.rb +13 -9
- data/lib/sdl/exporters/exporter.rb +10 -14
- data/lib/sdl/exporters/markdown_service_exporter.rb +0 -2
- data/lib/sdl/exporters/rdf_exporter.rb +17 -21
- data/lib/sdl/exporters/rdf_mapping.rb +0 -1
- data/lib/sdl/exporters/schema_exporter.rb +3 -7
- data/lib/sdl/exporters/service_exporter.rb +4 -8
- data/lib/sdl/exporters/xml_service_exporter.rb +22 -26
- data/lib/sdl/exporters/xsd_schema_exporter.rb +65 -70
- data/lib/sdl/ng/version.rb +1 -1
- data/lib/sdl/receivers.rb +7 -6
- data/lib/sdl/receivers/fact_receiver.rb +8 -12
- data/lib/sdl/receivers/service_receiver.rb +41 -47
- data/lib/sdl/receivers/type_instance_receiver.rb +67 -73
- data/lib/sdl/receivers/type_receiver.rb +72 -76
- data/lib/sdl/types.rb +15 -9
- data/lib/sdl/types/sdl_datetime.rb +4 -8
- data/lib/sdl/types/sdl_description.rb +6 -10
- data/lib/sdl/types/sdl_duration.rb +4 -8
- data/lib/sdl/types/sdl_number.rb +4 -8
- data/lib/sdl/types/sdl_simple_type.rb +13 -6
- data/lib/sdl/types/sdl_string.rb +4 -8
- data/lib/sdl/types/sdl_type.rb +20 -24
- data/lib/sdl/types/sdl_url.rb +9 -13
- data/lib/sdl/util.rb +1 -0
- metadata +2 -2
@@ -1,90 +1,84 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
define_singleton_method property.name do |value = nil, &block|
|
23
|
-
if value.is_a? Symbol
|
24
|
-
value = compendium.type_instances[property.type][value] || raise("Could not find instance :#{value.to_s} in predefined #{property.type.name} types")
|
25
|
-
end
|
1
|
+
##
|
2
|
+
# Receiver for setting the properties of Type instances
|
3
|
+
class SDL::Receivers::TypeInstanceReceiver
|
4
|
+
attr_accessor :instance
|
5
|
+
|
6
|
+
attr_accessor :compendium
|
7
|
+
|
8
|
+
##
|
9
|
+
# When initialized for a fact or type instance, the receiver creates singleton methods on itself for all
|
10
|
+
# properties.
|
11
|
+
def initialize(instance, compendium)
|
12
|
+
@instance = instance
|
13
|
+
@compendium = compendium
|
14
|
+
|
15
|
+
instance.class.properties(true).each do |property|
|
16
|
+
if property.single?
|
17
|
+
# Single valued properties are set by their name
|
18
|
+
define_singleton_method property.name do |value = nil, &block|
|
19
|
+
if value.is_a? Symbol
|
20
|
+
value = compendium.type_instances[property.type][value] || raise("Could not find instance :#{value.to_s} in predefined #{property.type.name} types")
|
21
|
+
end
|
26
22
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
23
|
+
begin
|
24
|
+
instance.send "#{property.name}=", value
|
25
|
+
rescue RuntimeError => e
|
26
|
+
raise RuntimeError, "Cannot set property '#{property.name}' of Type #{@instance.class.name}: #{e}", e.backtrace
|
27
|
+
end
|
28
|
+
end
|
29
|
+
else
|
30
|
+
# Multi-valued properties are added to by their singular name
|
31
|
+
define_singleton_method property.name.singularize do |*property_values, &block|
|
32
|
+
existing_list = instance.send "#{property.name}"
|
33
|
+
|
34
|
+
unless property_values.empty?
|
35
|
+
# If there is just one parameter for a multi-valued property setter
|
36
|
+
if property_values.length == 1
|
37
|
+
# It could be a symbol, which would resolve to a predefined type instance of the same name
|
38
|
+
if property_values[0].is_a?(Symbol)
|
39
|
+
predefined_value = compendium.type_instances[property.type][property_values[0]]
|
40
|
+
|
41
|
+
raise "Could not find instance :#{property_values[0]} in predefined #{property.type.name} types" unless predefined_value
|
42
|
+
|
43
|
+
existing_list << compendium.type_instances[property.type][property_values[0]]
|
44
|
+
# Or better: it could already be an instance of the type - e.g. when using the implemented #method_mssing
|
45
|
+
elsif property_values[0].is_a? property.type
|
46
|
+
existing_list << property_values[0]
|
31
47
|
end
|
32
|
-
|
33
|
-
|
34
|
-
# Multi-valued properties are added to by their singular name
|
35
|
-
define_singleton_method property.name.singularize do |*property_values, &block|
|
36
|
-
existing_list = instance.send "#{property.name}"
|
37
|
-
|
38
|
-
unless property_values.empty?
|
39
|
-
# If there is just one parameter for a multi-valued property setter
|
40
|
-
if property_values.length == 1
|
41
|
-
# It could be a symbol, which would resolve to a predefined type instance of the same name
|
42
|
-
if property_values[0].is_a?(Symbol)
|
43
|
-
predefined_value = compendium.type_instances[property.type][property_values[0]]
|
48
|
+
else
|
49
|
+
new_list_item = property.type.new
|
44
50
|
|
45
|
-
|
51
|
+
SDL::Receivers.set_value(property.type, new_list_item, *property_values, @compendium)
|
46
52
|
|
47
|
-
|
48
|
-
# Or better: it could already be an instance of the type - e.g. when using the implemented #method_mssing
|
49
|
-
elsif property_values[0].is_a? property.type
|
50
|
-
existing_list << property_values[0]
|
51
|
-
end
|
52
|
-
else
|
53
|
-
new_list_item = property.type.new
|
53
|
+
self.class.new(new_list_item, @compendium).instance_exec(&block) unless block.nil?
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
self.class.new(new_list_item, @compendium).instance_exec(&block) unless block.nil?
|
58
|
-
|
59
|
-
existing_list << new_list_item
|
60
|
-
end
|
61
|
-
end
|
55
|
+
existing_list << new_list_item
|
62
56
|
end
|
63
57
|
end
|
64
58
|
end
|
65
59
|
end
|
60
|
+
end
|
61
|
+
end
|
66
62
|
|
67
|
-
|
68
|
-
|
69
|
-
|
63
|
+
def annotation(value)
|
64
|
+
@instance.annotations << value
|
65
|
+
end
|
70
66
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
67
|
+
##
|
68
|
+
# Catches calls to methods named similarily to possible predefined type instances
|
69
|
+
def method_missing(name, *args)
|
70
|
+
# Possible type instances are all types of properties of properties of this instance ...
|
71
|
+
possible_type_classes = @instance.class.properties.map(&:type).map(&:properties).flatten.map(&:type).select{|type| type.wrapped_type < SDL::Base::Type}
|
76
72
|
|
77
|
-
|
78
|
-
|
73
|
+
# ... and the types of multi-value instances
|
74
|
+
possible_type_classes.concat(@instance.class.properties.find_all{|p| p.multi?}.map(&:type))
|
79
75
|
|
80
|
-
|
76
|
+
possible_type_instances = @compendium.type_instances.select{|k, v| possible_type_classes.include?(k)}.map{|k, v| v[name]}.select{|v| v != nil}
|
81
77
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
end
|
87
|
-
end
|
78
|
+
unless possible_type_instances.nil? || possible_type_instances.empty?
|
79
|
+
possible_type_instances[0]
|
80
|
+
else
|
81
|
+
raise Exception.new("I do not know what to do with '#{name}' in #{caller[0]}")
|
88
82
|
end
|
89
83
|
end
|
90
84
|
end
|
@@ -1,96 +1,92 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
class TypeReceiver
|
4
|
-
include ActiveSupport::Inflector
|
1
|
+
class SDL::Receivers::TypeReceiver
|
2
|
+
include ActiveSupport::Inflector
|
5
3
|
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
attr :klass
|
5
|
+
attr :subclasses
|
6
|
+
attr :compendium
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
def initialize(sym, compendium, superklass = nil)
|
9
|
+
@compendium = compendium
|
10
|
+
@klass = Class.new(superklass || base_class)
|
11
|
+
@klass.local_name = sym.to_s.camelize
|
14
12
|
|
15
|
-
|
13
|
+
@subclasses = [@klass]
|
16
14
|
|
17
|
-
|
18
|
-
|
15
|
+
register_sdltype(@klass)
|
16
|
+
end
|
19
17
|
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
def base_class
|
19
|
+
SDL::Base::Type
|
20
|
+
end
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
def register_sdltype(klass)
|
23
|
+
klass.class_eval do
|
24
|
+
include SDL::Types::SDLType
|
27
25
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
wraps self
|
27
|
+
codes local_name.underscore.to_sym
|
28
|
+
end
|
29
|
+
end
|
32
30
|
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
def subtype(sym, &definition)
|
32
|
+
receiver = self.class.new(sym, @compendium, @klass)
|
33
|
+
receiver.instance_eval(&definition) if block_given?
|
36
34
|
|
37
|
-
|
38
|
-
|
35
|
+
@subclasses.concat(receiver.subclasses)
|
36
|
+
end
|
39
37
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
38
|
+
##
|
39
|
+
# Define a list of a type, which is defined in the block.
|
40
|
+
def list(name, &block)
|
41
|
+
list_type = @compendium.type name.to_s.singularize.to_sym, &block
|
44
42
|
|
45
|
-
|
46
|
-
|
43
|
+
add_property name.to_sym, list_type, true
|
44
|
+
end
|
47
45
|
|
48
|
-
|
49
|
-
|
46
|
+
def method_missing(name, *args, &block)
|
47
|
+
sym = args[0] || name.to_sym
|
50
48
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
49
|
+
if name =~ /list_of_/
|
50
|
+
multi = true
|
51
|
+
type = @compendium.sdltype_codes[name.to_s.gsub('list_of_', '').singularize.to_sym]
|
52
|
+
else
|
53
|
+
multi = false
|
54
|
+
type = @compendium.sdltype_codes[name.to_sym]
|
55
|
+
end
|
58
56
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
57
|
+
if type
|
58
|
+
add_property sym, type, multi
|
59
|
+
else
|
60
|
+
super(name, *args, &block)
|
61
|
+
end
|
62
|
+
end
|
65
63
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
else
|
84
|
-
# Define accessor method for lists
|
85
|
-
@klass.class_eval do
|
86
|
-
define_method sym do
|
87
|
-
eval "@#{sym} ||= []"
|
88
|
-
end
|
64
|
+
private
|
65
|
+
##
|
66
|
+
# Adds accessors to set the property to the target class.
|
67
|
+
def add_property(sym, type, multi)
|
68
|
+
unless multi
|
69
|
+
@klass.class_eval do
|
70
|
+
attr_reader sym
|
71
|
+
|
72
|
+
# Setter
|
73
|
+
define_method "#{sym}=" do |value|
|
74
|
+
if type < SDL::Types::SDLSimpleType
|
75
|
+
instance_variable_set "@#{sym}".to_s, type.new(value)
|
76
|
+
else
|
77
|
+
instance_variable_set "@#{sym}".to_s, value
|
89
78
|
end
|
90
79
|
end
|
91
|
-
|
92
|
-
@klass.properties << SDL::Base::Property.new(sym, type, @klass, multi)
|
93
80
|
end
|
81
|
+
else
|
82
|
+
# Define accessor method for lists
|
83
|
+
@klass.class_eval do
|
84
|
+
define_method sym do
|
85
|
+
eval "@#{sym} ||= []"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
@klass.properties << SDL::Base::Property.new(sym, type, @klass, multi)
|
94
91
|
end
|
95
|
-
end
|
96
92
|
end
|
data/lib/sdl/types.rb
CHANGED
@@ -1,12 +1,3 @@
|
|
1
|
-
require_relative 'types/sdl_type'
|
2
|
-
require_relative 'types/sdl_simple_type'
|
3
|
-
require_relative 'types/sdl_string'
|
4
|
-
require_relative 'types/sdl_description'
|
5
|
-
require_relative 'types/sdl_number'
|
6
|
-
require_relative 'types/sdl_duration'
|
7
|
-
require_relative 'types/sdl_url'
|
8
|
-
require_relative 'types/sdl_datetime'
|
9
|
-
|
10
1
|
module SDL
|
11
2
|
##
|
12
3
|
# This module contains the SDL type system.
|
@@ -15,5 +6,20 @@ module SDL
|
|
15
6
|
# * When setting a property, its new value is checked for type compatibility to the wrapped Ruby class
|
16
7
|
# * When exporting a service description, the wrapper is used to determine the serialization format
|
17
8
|
module Types
|
9
|
+
extend ActiveSupport::Autoload
|
10
|
+
|
11
|
+
# Required, as these types register Receiver methods for their usage in property definitions.
|
12
|
+
eager_autoload do
|
13
|
+
autoload :SDLType
|
14
|
+
autoload :SDLSimpleType
|
15
|
+
autoload :SDLDatetime
|
16
|
+
autoload :SDLDescription
|
17
|
+
autoload :SDLDuration
|
18
|
+
autoload :SDLNumber
|
19
|
+
autoload :SDLString
|
20
|
+
autoload :SDLUrl
|
21
|
+
end
|
22
|
+
|
23
|
+
eager_load!
|
18
24
|
end
|
19
25
|
end
|
@@ -1,14 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
class SDLDescription < SDLSimpleType
|
4
|
-
include SDLType
|
1
|
+
class SDL::Types::SDLDescription < SDL::Types::SDLSimpleType
|
2
|
+
include SDL::Types::SDLType
|
5
3
|
|
6
|
-
|
7
|
-
|
4
|
+
wraps String
|
5
|
+
codes :description
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
end
|
7
|
+
def from_nilclass(nilvalue)
|
8
|
+
@value = ""
|
13
9
|
end
|
14
10
|
end
|
@@ -1,12 +1,8 @@
|
|
1
1
|
require 'active_support/duration'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
class SDLDuration < SDLSimpleType
|
6
|
-
include SDLType
|
3
|
+
class SDL::Types::SDLDuration < SDL::Types::SDLSimpleType
|
4
|
+
include SDL::Types::SDLType
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
end
|
6
|
+
wraps ActiveSupport::Duration
|
7
|
+
codes :duration
|
12
8
|
end
|
data/lib/sdl/types/sdl_number.rb
CHANGED
@@ -1,10 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
class SDLNumber < SDLSimpleType
|
4
|
-
include SDLType
|
1
|
+
class SDL::Types::SDLNumber < SDL::Types::SDLSimpleType
|
2
|
+
include SDL::Types::SDLType
|
5
3
|
|
6
|
-
|
7
|
-
|
8
|
-
end
|
9
|
-
end
|
4
|
+
wraps Numeric
|
5
|
+
codes :number, :int, :integer
|
10
6
|
end
|
@@ -5,6 +5,19 @@
|
|
5
5
|
class SDL::Types::SDLSimpleType
|
6
6
|
include SDL::Types::SDLType
|
7
7
|
|
8
|
+
##
|
9
|
+
# Array of all SDLSimpleTypes. Used by the ServiceCompendium.
|
10
|
+
def self.sdl_types
|
11
|
+
@@sdl_types ||= []
|
12
|
+
end
|
13
|
+
|
14
|
+
##
|
15
|
+
# Every descendant of SDLSimpleType registers it with this class, so that all ServiceCompendiums
|
16
|
+
# recognize the codes of descendants.
|
17
|
+
def self.inherited(subclass)
|
18
|
+
sdl_types << subclass
|
19
|
+
end
|
20
|
+
|
8
21
|
# The SDL value type value, possibly converted to the wrapped ruby type, e.g., an URI object created from an
|
9
22
|
# "http://" String
|
10
23
|
attr_reader :value
|
@@ -44,12 +57,6 @@ class SDL::Types::SDLSimpleType
|
|
44
57
|
@value.to_s
|
45
58
|
end
|
46
59
|
|
47
|
-
##
|
48
|
-
# Designates this SDLType to be a default type, i.e., to be loaded by all ServiceCompendiums automatically
|
49
|
-
def self.inherited(subclass)
|
50
|
-
SDL::Base::ServiceCompendium.default_sdltypes << subclass
|
51
|
-
end
|
52
|
-
|
53
60
|
private
|
54
61
|
def conversion_method_name(value)
|
55
62
|
value.class.name.demodulize.camelize.downcase
|