omf_common 6.0.0.pre.10 → 6.0.0.pre.11
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/monitor_topic.rb +80 -0
- data/bin/send_create.rb +94 -0
- data/bin/send_request.rb +58 -0
- data/example/engine_alt.rb +136 -0
- data/example/vm_alt.rb +65 -0
- data/lib/omf_common.rb +224 -3
- data/lib/omf_common/comm.rb +113 -46
- data/lib/omf_common/comm/amqp/amqp_communicator.rb +76 -0
- data/lib/omf_common/comm/amqp/amqp_topic.rb +91 -0
- data/lib/omf_common/comm/local/local_communicator.rb +64 -0
- data/lib/omf_common/comm/local/local_topic.rb +42 -0
- data/lib/omf_common/comm/topic.rb +190 -0
- data/lib/omf_common/{dsl/xmpp.rb → comm/xmpp/communicator.rb} +93 -53
- data/lib/omf_common/comm/xmpp/topic.rb +147 -0
- data/lib/omf_common/{dsl → comm/xmpp}/xmpp_mp.rb +2 -0
- data/lib/omf_common/eventloop.rb +94 -0
- data/lib/omf_common/eventloop/em.rb +57 -0
- data/lib/omf_common/eventloop/local_evl.rb +78 -0
- data/lib/omf_common/message.rb +112 -229
- data/lib/omf_common/message/json/json_message.rb +129 -0
- data/lib/omf_common/message/xml/message.rb +410 -0
- data/lib/omf_common/message/xml/relaxng_schema.rb +17 -0
- data/lib/omf_common/message/xml/topic_message.rb +20 -0
- data/lib/omf_common/protocol/6.0.rnc +11 -21
- data/lib/omf_common/protocol/6.0.rng +52 -119
- data/lib/omf_common/version.rb +1 -1
- data/omf_common.gemspec +4 -2
- data/test/fixture/pubsub.rb +19 -19
- data/test/omf_common/{dsl/xmpp_spec.rb → comm/xmpp/communicator_spec.rb} +47 -111
- data/test/omf_common/comm/xmpp/topic_spec.rb +113 -0
- data/test/omf_common/comm_spec.rb +1 -0
- data/test/omf_common/message/xml/message_spec.rb +136 -0
- data/test/omf_common/message_spec.rb +37 -131
- data/test/test_helper.rb +4 -1
- metadata +38 -28
- data/lib/omf_common/core_ext/object.rb +0 -21
- data/lib/omf_common/relaxng_schema.rb +0 -17
- data/lib/omf_common/topic.rb +0 -34
- data/lib/omf_common/topic_message.rb +0 -20
- data/test/omf_common/topic_message_spec.rb +0 -114
- data/test/omf_common/topic_spec.rb +0 -75
@@ -0,0 +1,94 @@
|
|
1
|
+
module OmfCommon
|
2
|
+
# Providing event loop support.
|
3
|
+
class Eventloop
|
4
|
+
|
5
|
+
@@providers = {
|
6
|
+
em: {
|
7
|
+
require: 'omf_common/eventloop/em',
|
8
|
+
constructor: 'OmfCommon::Eventloop::EventMachine'
|
9
|
+
},
|
10
|
+
local: {
|
11
|
+
require: 'omf_common/eventloop/local_evl',
|
12
|
+
constructor: 'OmfCommon::Eventloop::Local'
|
13
|
+
}
|
14
|
+
}
|
15
|
+
@@instance = nil
|
16
|
+
|
17
|
+
#
|
18
|
+
# opts:
|
19
|
+
# :type - eventloop provider
|
20
|
+
# :provider - custom provider (opts)
|
21
|
+
# :require - gem to load first (opts)
|
22
|
+
# :constructor - Class implementing provider
|
23
|
+
#
|
24
|
+
def self.init(opts, &block)
|
25
|
+
if @@instance
|
26
|
+
raise "Eventloop provider already iniitalised"
|
27
|
+
end
|
28
|
+
unless provider = opts[:provider]
|
29
|
+
provider = @@providers[opts[:type].to_sym]
|
30
|
+
end
|
31
|
+
unless provider
|
32
|
+
raise "Missing Eventloop provider declaration. Either define 'type' or 'provider'"
|
33
|
+
end
|
34
|
+
|
35
|
+
require provider[:require] if provider[:require]
|
36
|
+
|
37
|
+
if class_name = provider[:constructor]
|
38
|
+
provider_class = class_name.split('::').inject(Object) {|c,n| c.const_get(n) }
|
39
|
+
inst = provider_class.new(opts, &block)
|
40
|
+
else
|
41
|
+
raise "Missing provider creation info - :constructor"
|
42
|
+
end
|
43
|
+
@@instance = inst
|
44
|
+
inst
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.instance
|
48
|
+
@@instance
|
49
|
+
end
|
50
|
+
|
51
|
+
# Execute block after some time
|
52
|
+
#
|
53
|
+
# @param [float] delay in sec
|
54
|
+
# @param [block] block to execute
|
55
|
+
#
|
56
|
+
def after(delay_sec, &block)
|
57
|
+
raise "Missing implementation 'after'"
|
58
|
+
end
|
59
|
+
|
60
|
+
# Periodically call block every interval_sec
|
61
|
+
#
|
62
|
+
# @param [float] interval in sec
|
63
|
+
# @param [block] block to execute
|
64
|
+
#
|
65
|
+
def every(interval_sec, &block)
|
66
|
+
raise "Missing implementation 'every'"
|
67
|
+
end
|
68
|
+
|
69
|
+
# Block calling thread until eventloop exits
|
70
|
+
def join()
|
71
|
+
raise "Missing implementation 'join'"
|
72
|
+
end
|
73
|
+
|
74
|
+
def run()
|
75
|
+
raise "Missing implementation 'run'"
|
76
|
+
end
|
77
|
+
|
78
|
+
def stop()
|
79
|
+
raise "Missing implementation 'stop'"
|
80
|
+
end
|
81
|
+
|
82
|
+
# Calling 'block' before stopping eventloop
|
83
|
+
#
|
84
|
+
def on_stop(&block)
|
85
|
+
warn "Missing implementation 'on_stop'"
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
def initialize(opts = {}, &block)
|
90
|
+
#run(&block) if block
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
|
3
|
+
module OmfCommon
|
4
|
+
class Eventloop
|
5
|
+
# Implements a simple eventloop which only deals with timer events
|
6
|
+
#
|
7
|
+
class EventMachine < Eventloop
|
8
|
+
|
9
|
+
def initialize(opts = {}, &block)
|
10
|
+
super
|
11
|
+
@deferred = []
|
12
|
+
@deferred << block if block
|
13
|
+
end
|
14
|
+
|
15
|
+
# Execute block after some time
|
16
|
+
#
|
17
|
+
# @param [Float] delay in sec
|
18
|
+
def after(delay_sec, &block)
|
19
|
+
if EM.reactor_running?
|
20
|
+
EM.add_timer(delay_sec, &block)
|
21
|
+
else
|
22
|
+
@deferred << lambda do
|
23
|
+
EM.add_timer(delay_sec, &block)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Periodically call block every interval_sec
|
29
|
+
#
|
30
|
+
# @param [Float] interval in sec
|
31
|
+
def every(interval_sec, &block)
|
32
|
+
if EM.reactor_running?
|
33
|
+
EM.add_periodic_timer(interval_sec, &block)
|
34
|
+
else
|
35
|
+
@deferred << lambda do
|
36
|
+
EM.add_periodic_timer(interval_sec, &block)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def run(&block)
|
42
|
+
EM.run do
|
43
|
+
@deferred.each { |proc| proc.call }
|
44
|
+
@deferred = nil
|
45
|
+
if block
|
46
|
+
block.arity == 0 ? block.call : block.call(self)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def stop()
|
52
|
+
EM.stop
|
53
|
+
end
|
54
|
+
end # class
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,78 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module OmfCommon
|
4
|
+
class Eventloop
|
5
|
+
# Implements a simple eventloop which only deals with timer events
|
6
|
+
#
|
7
|
+
class Local < Eventloop
|
8
|
+
|
9
|
+
def initialize(opts = {}, &block)
|
10
|
+
super
|
11
|
+
@tasks = []
|
12
|
+
@running = false
|
13
|
+
after(0, &block) if block
|
14
|
+
end
|
15
|
+
|
16
|
+
# Execute block after some time
|
17
|
+
#
|
18
|
+
# @param [float] delay in sec
|
19
|
+
# @param [block] block to execute
|
20
|
+
#
|
21
|
+
def after(delay_sec, &block)
|
22
|
+
@tasks << [Time.now + delay_sec, block]
|
23
|
+
end
|
24
|
+
|
25
|
+
# Periodically call block every interval_sec
|
26
|
+
#
|
27
|
+
# @param [float] interval in sec
|
28
|
+
# @param [block] block to execute
|
29
|
+
#
|
30
|
+
def every(interval_sec, &block)
|
31
|
+
@tasks << [Time.now + interval_sec, block, :periodic => interval_sec]
|
32
|
+
end
|
33
|
+
|
34
|
+
def stop
|
35
|
+
@running = false
|
36
|
+
end
|
37
|
+
|
38
|
+
def run(&block)
|
39
|
+
after(0, &block) if block
|
40
|
+
return if @running
|
41
|
+
@running = true
|
42
|
+
|
43
|
+
while @running do
|
44
|
+
now = Time.now
|
45
|
+
@tasks = @tasks.sort
|
46
|
+
while @tasks[0] && @tasks[0][0] <= now
|
47
|
+
# execute
|
48
|
+
t = @tasks.shift
|
49
|
+
debug "Executing Task #{t}"
|
50
|
+
block = t[1]
|
51
|
+
block.arity == 0 ? block.call : block.call(self)
|
52
|
+
now = Time.now
|
53
|
+
# Check if periodic
|
54
|
+
if interval = ((t[2] || {})[:periodic])
|
55
|
+
if (next_time = t[0] + interval) < now
|
56
|
+
warn "Falling behind with periodic task #{t[1]}"
|
57
|
+
next_time = now + interval
|
58
|
+
end
|
59
|
+
@tasks << [next_time, t[1], :periodic => interval]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
# by now, there could have been a few more tasks added, so let's sort again
|
63
|
+
@tasks = @tasks.sort
|
64
|
+
if @tasks.empty?
|
65
|
+
# done
|
66
|
+
@running = false
|
67
|
+
else
|
68
|
+
if (delay = @tasks[0][0] - Time.now) > 0
|
69
|
+
debug "Sleeping #{delay}"
|
70
|
+
sleep delay
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end # class
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
data/lib/omf_common/message.rb
CHANGED
@@ -1,293 +1,176 @@
|
|
1
|
-
require 'niceogiri'
|
2
|
-
require 'hashie'
|
3
|
-
require 'securerandom'
|
4
|
-
require 'openssl'
|
5
|
-
require 'cgi'
|
6
|
-
require 'omf_common/relaxng_schema'
|
7
|
-
|
8
1
|
module OmfCommon
|
9
2
|
|
10
3
|
class MPMessage < OML4R::MPBase
|
11
4
|
name :message
|
12
5
|
param :time, :type => :double
|
13
6
|
param :operation, :type => :string
|
14
|
-
param :
|
15
|
-
param :
|
7
|
+
param :mid, :type => :string
|
8
|
+
param :cid, :type => :string
|
16
9
|
param :content, :type => :string
|
17
10
|
end
|
18
11
|
|
19
|
-
|
20
|
-
|
21
|
-
# @example To create a valid omf message, e.g. a 'configure' message:
|
22
|
-
#
|
23
|
-
# Message.request do |message|
|
24
|
-
# message.property('os', 'debian')
|
25
|
-
# message.property('memory', { value: 2, unit: 'gb' })
|
26
|
-
# end
|
27
|
-
#
|
28
|
-
class Message < Niceogiri::XML::Node
|
12
|
+
class Message
|
13
|
+
|
29
14
|
OMF_NAMESPACE = "http://schema.mytestbed.net/omf/#{OmfCommon::PROTOCOL_VERSION}/protocol"
|
30
|
-
|
31
|
-
|
32
|
-
# measurement twice, once when a message is created for publishing to T,
|
33
|
-
# and once when this message comes back (as we are also a subscriber of T)
|
34
|
-
# Thus we keep track of message IDs here (again only when OML is enabled)
|
35
|
-
@@msg_id_list = []
|
36
|
-
|
37
|
-
class << self
|
38
|
-
OPERATION.each do |operation|
|
39
|
-
define_method(operation) do |*args, &block|
|
40
|
-
xml = new(operation, nil, OMF_NAMESPACE)
|
41
|
-
if operation == 'inform'
|
42
|
-
xml.element('context_id', args[1]) if args[1]
|
43
|
-
xml.element('inform_type', args[0])
|
44
|
-
else
|
45
|
-
xml.element('publish_to', args[0]) if args[0]
|
46
|
-
end
|
47
|
-
block.call(xml) if block
|
48
|
-
xml.sign
|
49
|
-
end
|
50
|
-
end
|
15
|
+
OMF_CORE_READ = [:operation, :ts, :src, :mid, :replyto, :cid, :itype, :rtype, :guard, :res_id]
|
16
|
+
OMF_CORE_WRITE = [:replyto, :itype, :guard]
|
51
17
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
18
|
+
@@providers = {
|
19
|
+
xml: {
|
20
|
+
require: 'omf_common/message/xml/message',
|
21
|
+
constructor: 'OmfCommon::Message::XML::Message'
|
22
|
+
},
|
23
|
+
json: {
|
24
|
+
require: 'omf_common/message/json/json_message',
|
25
|
+
constructor: 'OmfCommon::Message::Json::Message'
|
26
|
+
}
|
27
|
+
}
|
28
|
+
@@message_class = nil
|
62
29
|
|
63
|
-
|
64
|
-
|
65
|
-
def property(key, value = nil)
|
66
|
-
key_node = Message.new('property')
|
67
|
-
key_node.write_attr('key', key)
|
68
|
-
|
69
|
-
unless value.nil?
|
70
|
-
key_node.write_attr('type', ruby_type_2_prop_type(value.class))
|
71
|
-
c_node = value_node_set(value)
|
72
|
-
|
73
|
-
if c_node.class == Array
|
74
|
-
c_node.each { |c_n| key_node.add_child(c_n) }
|
75
|
-
else
|
76
|
-
key_node.add_child(c_node)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
add_child(key_node)
|
80
|
-
key_node
|
30
|
+
def self.create(type, properties, body = {})
|
31
|
+
@@message_class.create(type, properties, body)
|
81
32
|
end
|
82
33
|
|
83
|
-
def
|
84
|
-
|
85
|
-
|
86
|
-
[].tap do |array|
|
87
|
-
value.each_pair do |k, v|
|
88
|
-
n = Message.new(k)
|
89
|
-
n.write_attr('type', ruby_type_2_prop_type(v.class))
|
90
|
-
|
91
|
-
c_node = value_node_set(v, k)
|
92
|
-
if c_node.class == Array
|
93
|
-
c_node.each { |c_n| n.add_child(c_n) }
|
94
|
-
else
|
95
|
-
n.add_child(c_node)
|
96
|
-
end
|
97
|
-
array << n
|
98
|
-
end
|
99
|
-
end
|
100
|
-
when Array
|
101
|
-
value.map do |v|
|
102
|
-
n = Message.new('item')
|
103
|
-
n.write_attr('type', ruby_type_2_prop_type(v.class))
|
104
|
-
|
105
|
-
c_node = value_node_set(v, 'item')
|
106
|
-
if c_node.class == Array
|
107
|
-
c_node.each { |c_n| n.add_child(c_n) }
|
108
|
-
else
|
109
|
-
n.add_child(c_node)
|
110
|
-
end
|
111
|
-
n
|
112
|
-
end
|
113
|
-
else
|
114
|
-
if key.nil?
|
115
|
-
string_value(value)
|
116
|
-
else
|
117
|
-
n = Message.new(key)
|
118
|
-
n.add_child(string_value(value))
|
119
|
-
end
|
120
|
-
end
|
34
|
+
def self.create_inform_message(itype = nil, properties = {}, body = {})
|
35
|
+
body[:itype] = itype if itype
|
36
|
+
create(:inform, properties, body)
|
121
37
|
end
|
122
38
|
|
123
|
-
#
|
39
|
+
# Create and return a message by parsing 'str'
|
124
40
|
#
|
125
|
-
def
|
126
|
-
|
127
|
-
|
128
|
-
canonical_msg = self.canonicalize
|
41
|
+
def self.parse(str)
|
42
|
+
@@message_class.parse(str)
|
43
|
+
end
|
129
44
|
|
130
|
-
|
131
|
-
|
45
|
+
def self.init(opts = {})
|
46
|
+
if @@message_class
|
47
|
+
raise "Message provider already iniitalised"
|
48
|
+
end
|
49
|
+
unless provider = opts[:provider]
|
50
|
+
provider = @@providers[opts[:type]]
|
51
|
+
end
|
52
|
+
unless provider
|
53
|
+
raise "Missing Message provider declaration. Either define 'type' or 'provider'"
|
54
|
+
end
|
132
55
|
|
133
|
-
|
134
|
-
write_attr('digest', digest)
|
135
|
-
write_attr('signature', signature) if signature
|
56
|
+
require provider[:require] if provider[:require]
|
136
57
|
|
137
|
-
if
|
138
|
-
|
139
|
-
|
58
|
+
if class_name = provider[:constructor]
|
59
|
+
@@message_class = class_name.split('::').inject(Object) {|c,n| c.const_get(n) }
|
60
|
+
else
|
61
|
+
raise "Missing provider class info - :constructor"
|
140
62
|
end
|
141
|
-
self
|
142
63
|
end
|
143
64
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
65
|
+
OMF_CORE_READ.each do |pname|
|
66
|
+
define_method(pname.to_s) do |*args|
|
67
|
+
_get_core(pname)
|
68
|
+
end
|
69
|
+
end
|
149
70
|
|
71
|
+
alias_method :type, :operation
|
150
72
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
validation = RelaxNGSchema.instance.schema.validate(self.document)
|
155
|
-
if validation.empty?
|
156
|
-
true
|
157
|
-
else
|
158
|
-
logger.error validation.map(&:message).join("\n")
|
159
|
-
logger.debug self.to_s
|
160
|
-
false
|
73
|
+
OMF_CORE_WRITE.each do |pname|
|
74
|
+
define_method("#{pname}=") do |val|
|
75
|
+
_set_core(pname.to_sym, val)
|
161
76
|
end
|
162
77
|
end
|
163
78
|
|
164
|
-
#
|
79
|
+
# To access properties
|
165
80
|
#
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
block.call(key_node)
|
171
|
-
else
|
172
|
-
key_node.content = value if value
|
173
|
-
end
|
81
|
+
# @param [String] name of the property
|
82
|
+
# @param [Hash] ns namespace of property
|
83
|
+
def [](name, ns = nil)
|
84
|
+
_get_property(name.to_sym, ns)
|
174
85
|
end
|
175
86
|
|
176
|
-
#
|
87
|
+
# To set properties
|
177
88
|
#
|
178
|
-
|
179
|
-
|
89
|
+
# @param [String] name of the property
|
90
|
+
# @param [Hash] ns namespace of property
|
91
|
+
def []=(name, ns = nil, value)
|
92
|
+
# TODO why itype cannot be set?
|
93
|
+
#raise if name.to_sym == :itype
|
94
|
+
if ns
|
95
|
+
@props_ns ||= {}
|
96
|
+
@props_ns.merge(ns)
|
97
|
+
end
|
98
|
+
_set_property(name.to_sym, value, ns)
|
180
99
|
end
|
181
100
|
|
182
|
-
|
183
|
-
|
184
|
-
xpath(xpath_without_ns.gsub(/(^|\/{1,2})(\w+)/, '\1xmlns:\2'), :xmlns => OMF_NAMESPACE)
|
101
|
+
def each_property(&block)
|
102
|
+
raise NotImplementedError
|
185
103
|
end
|
186
104
|
|
187
|
-
#
|
105
|
+
# Loop over all the unbound (sent without a value) properties
|
106
|
+
# of a request message.
|
188
107
|
#
|
189
|
-
|
108
|
+
def each_unbound_request_property(&block)
|
109
|
+
raise NotImplementedError
|
110
|
+
end
|
190
111
|
|
191
|
-
#
|
112
|
+
# Loop over all the bound (sent with a value) properties
|
113
|
+
# of a request message.
|
192
114
|
#
|
193
|
-
def
|
194
|
-
|
195
|
-
unless element_content.nil?
|
196
|
-
element_content.empty? ? nil : element_content
|
197
|
-
else
|
198
|
-
nil
|
199
|
-
end
|
115
|
+
def each_bound_request_property(&block)
|
116
|
+
raise NotImplementedError
|
200
117
|
end
|
201
118
|
|
202
|
-
|
203
|
-
|
204
|
-
read_property(:context_id) || read_content(:context_id)
|
119
|
+
def has_properties?
|
120
|
+
raise NotImplementedError
|
205
121
|
end
|
206
122
|
|
207
|
-
|
208
|
-
|
209
|
-
|
123
|
+
def resource
|
124
|
+
name = _get_property(:res_id)
|
125
|
+
OmfCommon.comm.create_topic(name)
|
210
126
|
end
|
211
127
|
|
212
|
-
def
|
213
|
-
|
128
|
+
def success?
|
129
|
+
! error?
|
214
130
|
end
|
215
131
|
|
216
|
-
def
|
217
|
-
|
132
|
+
def error?
|
133
|
+
(itype || '') =~ /(error|ERROR|FAILED)/
|
218
134
|
end
|
219
135
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
# @return [Object] the content of the property, as string, integer, float, or mash(hash with indifferent access)
|
224
|
-
#
|
225
|
-
def read_property(key, data_binding = nil)
|
226
|
-
key = key.to_s
|
227
|
-
e = read_element("property[@key='#{key}']").first
|
228
|
-
reconstruct_data(e, data_binding) if e
|
136
|
+
def create_inform_reply_message(itype = nil, properties = {}, body = {})
|
137
|
+
body[:cid] = self.mid
|
138
|
+
self.class.create_inform_message(itype, properties, body)
|
229
139
|
end
|
230
140
|
|
231
|
-
def
|
232
|
-
|
233
|
-
case node_type
|
234
|
-
when 'array'
|
235
|
-
node.element_children.map do |child|
|
236
|
-
reconstruct_data(child, data_binding)
|
237
|
-
end
|
238
|
-
when /hash/
|
239
|
-
mash ||= Hashie::Mash.new
|
240
|
-
node.element_children.each do |child|
|
241
|
-
mash[child.attr('key') || child.element_name] ||= reconstruct_data(child, data_binding)
|
242
|
-
end
|
243
|
-
mash
|
244
|
-
when /boolean/
|
245
|
-
node.content == "true"
|
246
|
-
else
|
247
|
-
if node.content.empty?
|
248
|
-
nil
|
249
|
-
elsif data_binding && node_type == 'string'
|
250
|
-
ERB.new(node.content).result(data_binding)
|
251
|
-
else
|
252
|
-
node.content.ducktype
|
253
|
-
end
|
254
|
-
end
|
141
|
+
def to_s
|
142
|
+
raise NotImplementedError
|
255
143
|
end
|
256
144
|
|
257
|
-
|
258
|
-
|
259
|
-
def each_property(&block)
|
260
|
-
read_element("property").each { |v| block.call(v) }
|
145
|
+
def marshall
|
146
|
+
raise NotImplementedError
|
261
147
|
end
|
262
148
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
149
|
+
def valid?
|
150
|
+
raise NotImplementedError
|
151
|
+
end
|
152
|
+
|
153
|
+
# Construct default namespace of the props from resource type
|
154
|
+
def default_props_ns
|
155
|
+
resource_type = _get_core(:rtype)
|
156
|
+
resource_type ? { resource_type.to_s => "#{OMF_NAMESPACE}/#{resource_type}" } : {}
|
157
|
+
end
|
158
|
+
|
159
|
+
# Get all property namespace defs
|
160
|
+
def props_ns
|
161
|
+
@props_ns ||= {}
|
162
|
+
default_props_ns.merge(@props_ns)
|
267
163
|
end
|
268
164
|
|
269
165
|
private
|
270
166
|
|
271
|
-
def
|
272
|
-
|
273
|
-
case v_type
|
274
|
-
when *%w(trueclass falseclass)
|
275
|
-
'boolean'
|
276
|
-
when *%w(fixnum bignum)
|
277
|
-
'integer'
|
278
|
-
else
|
279
|
-
v_type
|
280
|
-
end
|
167
|
+
def _get_property(name, ns = nil)
|
168
|
+
raise NotImplementedError
|
281
169
|
end
|
282
170
|
|
283
|
-
|
284
|
-
|
285
|
-
if value.kind_of? String
|
286
|
-
value = CGI::escape_html(value)
|
287
|
-
else
|
288
|
-
value = value.to_s
|
289
|
-
end
|
290
|
-
value
|
171
|
+
def _set_property(name, value, ns = nil)
|
172
|
+
raise NotImplementedError
|
291
173
|
end
|
292
174
|
end
|
175
|
+
|
293
176
|
end
|