ruby-vobject 0.1.0 → 1.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 +5 -5
- data/.hound.yml +3 -0
- data/.rubocop.tb.yml +650 -0
- data/.rubocop.yml +1077 -0
- data/.travis.yml +16 -3
- data/Gemfile +1 -1
- data/LICENSE.txt +21 -17
- data/README.adoc +142 -0
- data/Rakefile +1 -1
- data/lib/c.rb +173 -0
- data/lib/error.rb +19 -0
- data/lib/vcalendar.rb +77 -0
- data/lib/vcard.rb +67 -0
- data/lib/vobject.rb +13 -170
- data/lib/vobject/component.rb +87 -36
- data/lib/vobject/parameter.rb +116 -0
- data/lib/vobject/parametervalue.rb +26 -0
- data/lib/vobject/property.rb +134 -55
- data/lib/vobject/propertyvalue.rb +46 -0
- data/lib/vobject/vcalendar/component.rb +106 -0
- data/lib/vobject/vcalendar/grammar.rb +595 -0
- data/lib/vobject/vcalendar/paramcheck.rb +259 -0
- data/lib/vobject/vcalendar/propertyparent.rb +98 -0
- data/lib/vobject/vcalendar/propertyvalue.rb +606 -0
- data/lib/vobject/vcalendar/typegrammars.rb +605 -0
- data/lib/vobject/vcard/v3_0/component.rb +40 -0
- data/lib/vobject/vcard/v3_0/grammar.rb +176 -0
- data/lib/vobject/vcard/v3_0/paramcheck.rb +111 -0
- data/lib/vobject/vcard/v3_0/parameter.rb +17 -0
- data/lib/vobject/vcard/v3_0/property.rb +18 -0
- data/lib/vobject/vcard/v3_0/propertyvalue.rb +401 -0
- data/lib/vobject/vcard/v3_0/typegrammars.rb +426 -0
- data/lib/vobject/vcard/v4_0/component.rb +40 -0
- data/lib/vobject/vcard/v4_0/grammar.rb +225 -0
- data/lib/vobject/vcard/v4_0/paramcheck.rb +270 -0
- data/lib/vobject/vcard/v4_0/parameter.rb +18 -0
- data/lib/vobject/vcard/v4_0/property.rb +63 -0
- data/lib/vobject/vcard/v4_0/propertyvalue.rb +404 -0
- data/lib/vobject/vcard/v4_0/typegrammars.rb +540 -0
- data/lib/vobject/vcard/version.rb +3 -0
- data/lib/vobject/version.rb +1 -1
- data/ruby-vobject.gemspec +19 -11
- metadata +93 -17
- data/README.md +0 -94
data/lib/vcard.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require "vobject"
|
2
|
+
require "vobject/component"
|
3
|
+
|
4
|
+
class Vcard < Vobject::Component
|
5
|
+
attr_accessor :version
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def blank(version)
|
9
|
+
new VERSION: { value: version }
|
10
|
+
end
|
11
|
+
|
12
|
+
def decode(vcard_str, version = nil)
|
13
|
+
version_str = version.nil? ? "4.0" : /\nVERSION:([^\n\r]+)/i.match(vcard_str)[1]
|
14
|
+
blank(version_str).parse(vcard_str)
|
15
|
+
end
|
16
|
+
|
17
|
+
def parse(vcf, version, strict)
|
18
|
+
hash = version == "3.0" ? Vcard::V3_0::Component.parse(vcf, strict) : Vcard::V4_0::Component.parse(vcf, strict)
|
19
|
+
# comp_name = hash.keys.first
|
20
|
+
# return self.new(comp_name, hash[:vobject][comp_name], hash[:errors] )
|
21
|
+
hash
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def raise_invalid_parsing
|
27
|
+
raise "vCard parse failed"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(version)
|
32
|
+
self.version = version
|
33
|
+
super VCARD: { VERSION: { value: version } }
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def name
|
39
|
+
:VCARD
|
40
|
+
end
|
41
|
+
|
42
|
+
def property_base_class
|
43
|
+
version == "3.0" ? Vcard::V3_0::Property : Vcard::V4_0::Property
|
44
|
+
# version_class.const_get(:Property)
|
45
|
+
end
|
46
|
+
|
47
|
+
def component_base_class
|
48
|
+
version == "3.0" ? Vcard::V3_0::Component : Vcard::V4_0::Component
|
49
|
+
# version_class.const_get(:Component)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def require_dir(dir)
|
54
|
+
base = File.expand_path("../", __FILE__)
|
55
|
+
Dir.glob(File.join(base, dir, "**", "*.rb")).each do |path|
|
56
|
+
require path.gsub(/\.rb\Z/, "")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
require "vobject/vcard/v4_0/component"
|
61
|
+
require "vobject/vcard/v4_0/property"
|
62
|
+
require_dir "vobject/vcard/v4_0/component"
|
63
|
+
require_dir "vobject/vcard/v4_0/property"
|
64
|
+
require "vobject/vcard/v3_0/component"
|
65
|
+
require "vobject/vcard/v3_0/property"
|
66
|
+
require_dir "vobject/vcard/v3_0/component"
|
67
|
+
require_dir "vobject/vcard/v3_0/property"
|
data/lib/vobject.rb
CHANGED
@@ -1,182 +1,25 @@
|
|
1
|
-
require "vobject/version"
|
2
|
-
|
3
1
|
module Vobject
|
4
|
-
|
5
|
-
module Rules
|
6
|
-
|
7
|
-
module ABNF
|
8
|
-
IANAToken = '[a-zA-Z\d\-]+?'
|
9
|
-
Cr = "\u000d"
|
10
|
-
Lf = "\u000a"
|
11
|
-
Crlf = "(#{Cr}|#{Lf})"
|
12
|
-
Utf8_tail = '[\u0080-\u00bf]'
|
13
|
-
Utf8_2 = '([\u00c2-\u00df]|' + "#{Utf8_tail})"
|
14
|
-
Utf8_3 = '([\u00e0\u00a0-\u00bf\u00e1-\u00ec\u00ed\u0080-\u009f\u00ee-\u00ef]|' + "#{Utf8_tail})"
|
15
|
-
Utf8_4 = '([\u00f0\u0090-\u00bf\u00f1-\u00f3\u00f4\u0080-\u008f]|' + "#{Utf8_tail})"
|
16
|
-
Wsp = '[ \t]'
|
17
|
-
VChar = '[\u0021-\u007e]'
|
18
|
-
NonASCII = "(#{Utf8_2}|#{Utf8_3}|#{Utf8_4})"
|
19
|
-
QSafeChar = "(#{Wsp}|" + '[!\u0023-\u007e]' + "|#{NonASCII})"
|
20
|
-
SafeChar = "(#{Wsp}|" + '[!\u0023-\u0039\u003c-\u007e]' + "|#{NonASCII})"
|
21
|
-
ValueChar = "(#{Wsp}|#{VChar}|#{NonASCII})"
|
22
|
-
DQuote = '"'
|
23
|
-
PText = "#{SafeChar}*?"
|
24
|
-
QuotedString = "#{DQuote}(#{QSafeChar}*?)#{DQuote}"
|
25
|
-
XName = "[xX]-#{IANAToken}"
|
26
|
-
Group = IANAToken
|
27
|
-
Name = "(#{XName}|#{IANAToken})"
|
28
|
-
ParamName = "(#{XName}|#{IANAToken})"
|
29
|
-
ParamValue = "(#{PText}|#{QuotedString})"
|
30
|
-
PValueList = "(?<head>#{ParamValue})(?<tail>(,#{ParamValue})*)"
|
31
|
-
Pid = '\d+(\.\d+)*'
|
32
|
-
PidList = "(?<head>#{Pid})(?<tail>(,#{Pid})*)"
|
33
|
-
Param = "(?<pname>#{ParamName})=(?<pvalue>#{PValueList})"
|
34
|
-
Params = "(;(?<phead>#{Param}))(?<ptail>(;#{Param})*)"
|
35
|
-
Value = "#{ValueChar}*?"
|
36
|
-
LineGroup = "((?<group>#{Group})" + '\.' + ")?"
|
37
|
-
Contentline = "#{LineGroup}(?<key>#{Name})(?<params>(#{Params})?):(?<value>#{Value})#{Crlf}"
|
38
|
-
BeginLine = "BEGIN:#{IANAToken}#{Crlf}"
|
39
|
-
VersionLine = "VERSION:#{Value}#{Crlf}"
|
40
|
-
EndLine = "END:#{IANAToken}#{Crlf}"
|
41
|
-
Vobject = "#{BeginLine}#{VersionLine}(#{Contentline})+#{EndLine}"
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
2
|
class << self
|
47
|
-
|
48
|
-
def parse(vobject)
|
49
|
-
vobject = unfold(vobject)
|
50
|
-
lines = []
|
51
|
-
rule = "(?<line>#{Rules::ABNF::Contentline})(?<remainder>(#{Rules::ABNF::Contentline})*)"
|
52
|
-
|
53
|
-
parse_for_rule(Rules::ABNF::Vobject, vobject) do |parsed|
|
54
|
-
|
55
|
-
remainder = vobject
|
56
|
-
|
57
|
-
while !remainder.empty?
|
58
|
-
parse_for_rule(rule, remainder) do |remainder_parsed|
|
59
|
-
lines << remainder_parsed[:line]
|
60
|
-
remainder = remainder_parsed[:remainder]
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
parse_lines lines
|
66
|
-
end
|
67
|
-
|
68
|
-
private
|
69
|
-
|
3
|
+
MAX_LINE_WIDTH = 75
|
70
4
|
def unfold(str)
|
71
|
-
str.gsub(
|
72
|
-
end
|
73
|
-
|
74
|
-
def parse_lines lines
|
75
|
-
lines.each_with_index.reduce([]) do |hash_stack, (line, i)|
|
76
|
-
prop = parse_line(line)
|
77
|
-
|
78
|
-
if prop.has_key?(:BEGIN)
|
79
|
-
comp = prop[:BEGIN][:value].to_sym
|
80
|
-
hash = { comp => [] }
|
81
|
-
next hash_stack << hash
|
82
|
-
end
|
83
|
-
|
84
|
-
if prop.has_key?(:END)
|
85
|
-
hash = hash_stack.pop
|
86
|
-
comp = hash.keys.first
|
87
|
-
|
88
|
-
raise_invalid_parsing if comp != prop[:END][:value].to_sym
|
89
|
-
|
90
|
-
prev_hash = hash_stack.last
|
91
|
-
|
92
|
-
raise_invalid_parsing if !prev_hash && i != lines.length - 1
|
93
|
-
|
94
|
-
return hash unless prev_hash
|
95
|
-
|
96
|
-
prev_hash[prev_hash.keys.first] << hash
|
97
|
-
|
98
|
-
next hash_stack
|
99
|
-
end
|
100
|
-
|
101
|
-
prev_hash = hash_stack.last
|
102
|
-
|
103
|
-
prev_hash[prev_hash.keys.first] << prop
|
104
|
-
hash_stack
|
105
|
-
end
|
5
|
+
str.gsub(/(\r|\n|\r\n)[ \t]/, "")
|
106
6
|
end
|
107
7
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
value = parsed[:value]
|
115
|
-
|
116
|
-
hash = { key => {} }
|
117
|
-
hash[key][:group] = group if group
|
118
|
-
hash[key][:params] = params if !params.empty?
|
119
|
-
hash[key][:value] = value
|
120
|
-
|
121
|
-
hash
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
def parse_params(params_str)
|
126
|
-
params = {}
|
127
|
-
|
128
|
-
while !params_str.empty?
|
129
|
-
parse_for_rule(Rules::ABNF::Params, params_str) do |parsed|
|
130
|
-
|
131
|
-
parse_for_rule(Rules::ABNF::Param, parsed[:phead]) do |param_parsed|
|
132
|
-
pname = param_parsed[:pname].to_sym
|
133
|
-
pvalue = param_parsed[:pvalue].sub(
|
134
|
-
Regexp.new("^#{Rules::ABNF::QuotedString}$"),
|
135
|
-
'\1'
|
136
|
-
)
|
137
|
-
|
138
|
-
pvalue.gsub!(/\\n/, "\n")
|
8
|
+
# This implements the line folding as specified in
|
9
|
+
# http://tools.ietf.org/html/rfc6350#section-3.2
|
10
|
+
# NOTE: the "line" here is not including the trailing \n
|
11
|
+
def fold_line(line)
|
12
|
+
folded_line = line[0, MAX_LINE_WIDTH]
|
13
|
+
remainder_line = line[MAX_LINE_WIDTH, line.length - MAX_LINE_WIDTH] || ""
|
139
14
|
|
140
|
-
|
141
|
-
"#{params[pname]},#{pvalue}"
|
142
|
-
else
|
143
|
-
pvalue
|
144
|
-
end
|
145
|
-
end
|
15
|
+
max_width = MAX_LINE_WIDTH - 1
|
146
16
|
|
147
|
-
|
148
|
-
|
17
|
+
(0..((remainder_line.length - 1) / max_width)).each do |i|
|
18
|
+
folded_line << "\n "
|
19
|
+
folded_line << remainder_line[i * max_width, max_width]
|
149
20
|
end
|
150
21
|
|
151
|
-
|
22
|
+
folded_line
|
152
23
|
end
|
153
|
-
|
154
|
-
#Method: parse_for_rule
|
155
|
-
#Parameter: String containing the regular expression, String to be parsed
|
156
|
-
#and optional block to indicate whether to yield the resulting hash
|
157
|
-
#Return: a hash with keys indicating their regex names
|
158
|
-
def parse_for_rule(rule, str, &block)
|
159
|
-
matched = /\A#{rule}\Z/.match(str)
|
160
|
-
|
161
|
-
raise_invalid_parsing unless matched
|
162
|
-
|
163
|
-
parsed = matched.names.reduce({}) do |parsed_hash, name|
|
164
|
-
#can we reduce memory consumption by only creating Keys whose value is not nil?
|
165
|
-
parsed_hash[name.to_sym] = matched[name.to_sym] if matched[name.to_sym]
|
166
|
-
#parsed_hash[name.to_sym] = matched[name.to_sym]
|
167
|
-
parsed_hash
|
168
|
-
end
|
169
|
-
|
170
|
-
return yield(parsed) if block
|
171
|
-
|
172
|
-
parsed
|
173
|
-
end
|
174
|
-
|
175
|
-
def raise_invalid_parsing
|
176
|
-
raise "VObject parse failed"
|
177
|
-
end
|
178
|
-
|
179
24
|
end
|
180
|
-
|
181
25
|
end
|
182
|
-
|
data/lib/vobject/component.rb
CHANGED
@@ -1,64 +1,112 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "vobject"
|
2
|
+
require "vobject/property"
|
3
|
+
require "vobject/vcalendar/grammar"
|
4
|
+
require "json"
|
3
5
|
|
4
6
|
class Vobject::Component
|
7
|
+
attr_accessor :comp_name, :children, :multiple_components, :errors, :norm
|
5
8
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
hash = Vobject.parse(vcf)
|
12
|
-
comp_name = hash.keys.first
|
13
|
-
|
14
|
-
self.new comp_name, hash[comp_name]
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def raise_invalid_parsing
|
20
|
-
raise "Vobject component parse failed"
|
21
|
-
end
|
9
|
+
def <=>(another)
|
10
|
+
me = self.to_norm
|
11
|
+
o = another.to_norm
|
12
|
+
me <=> o
|
13
|
+
end
|
22
14
|
|
15
|
+
def blank(version)
|
16
|
+
ingest VOBJECT: { VERSION: { value: version } }
|
23
17
|
end
|
24
18
|
|
25
|
-
def initialize
|
19
|
+
def initialize(key, cs, err)
|
26
20
|
self.comp_name = key
|
27
|
-
|
28
21
|
raise_invalid_initialization if key != name
|
22
|
+
self.children = []
|
23
|
+
if cs.nil?
|
24
|
+
else
|
25
|
+
cs.each_key do |k|
|
26
|
+
val = cs[k]
|
27
|
+
# iteration of array || hash values is making the value a key!
|
28
|
+
next if k.class == Array
|
29
|
+
next if k.class == Hash
|
30
|
+
cc = child_class(k, val)
|
31
|
+
if val.is_a?(Hash) && val.has_key?(:component)
|
32
|
+
val[:component].each do |x|
|
33
|
+
children << cc.new(k, x, [])
|
34
|
+
end
|
35
|
+
else
|
36
|
+
children << cc.new(k, val)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
self.errors = err.select { |e| !e.nil? }
|
41
|
+
self.norm = nil
|
42
|
+
end
|
29
43
|
|
30
|
-
|
31
|
-
|
32
|
-
|
44
|
+
def get_errors
|
45
|
+
errors
|
46
|
+
end
|
33
47
|
|
34
|
-
|
35
|
-
|
36
|
-
|
48
|
+
def child_class(key, val)
|
49
|
+
base_class = if val.is_a?(Hash) && val.has_key?(:component)
|
50
|
+
component_base_class
|
51
|
+
elsif !(val.is_a?(Hash) && !val.has_key?(:value))
|
52
|
+
property_base_class
|
53
|
+
else
|
54
|
+
component_base_class
|
55
|
+
end
|
56
|
+
return base_class if [:CLASS, :OBJECT, :METHOD].include? key
|
57
|
+
camelized_key = key.to_s.downcase.split("_").map(&:capitalize).join("")
|
58
|
+
base_class.const_get(camelized_key) rescue base_class
|
37
59
|
end
|
38
60
|
|
39
61
|
def to_s
|
40
62
|
s = "BEGIN:#{name}\n"
|
41
|
-
|
42
63
|
children.each do |c|
|
43
64
|
s << c.to_s
|
44
65
|
end
|
45
|
-
|
46
66
|
s << "END:#{name}\n"
|
47
|
-
|
48
67
|
s
|
49
68
|
end
|
50
69
|
|
51
|
-
|
70
|
+
def to_norm
|
71
|
+
if norm.nil?
|
72
|
+
s = "BEGIN:#{name.upcase}\n"
|
73
|
+
properties = children.select { |c| c.is_a? Vobject::Property }
|
74
|
+
components = children.select { |c| not c.is_a? Vobject::Property }
|
75
|
+
# create to_norm in advance
|
76
|
+
properties.each { |p| p.to_norm }
|
77
|
+
properties.sort.each do |p|
|
78
|
+
s << p.to_norm
|
79
|
+
end
|
80
|
+
components.sort.each { |p| s << p.to_norm }
|
81
|
+
s << "END:#{name.upcase}\n"
|
82
|
+
norm = s
|
83
|
+
end
|
84
|
+
norm
|
85
|
+
end
|
86
|
+
|
87
|
+
def to_hash
|
88
|
+
a = {}
|
89
|
+
children.each do |c|
|
90
|
+
if c.is_a?(Vobject::Component)
|
91
|
+
a = a.merge(c.to_hash) { |_, old, new| [old, new].flatten }
|
92
|
+
elsif c.is_a?(Vobject::Property)
|
93
|
+
a = a.merge(c.to_hash) { |_, old, new| [old, new].flatten }
|
94
|
+
else
|
95
|
+
a[c.name] = c.to_hash
|
96
|
+
end
|
97
|
+
end
|
98
|
+
{ comp_name => a }
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_json
|
102
|
+
to_hash.to_json
|
103
|
+
end
|
52
104
|
|
53
105
|
def name
|
54
106
|
comp_name
|
55
107
|
end
|
56
108
|
|
57
|
-
|
58
|
-
base_class = val.is_a?(Array) ? component_base_class : property_base_class
|
59
|
-
camelized_key = key.to_s.downcase.split("_").map(&:capitalize).join("")
|
60
|
-
base_class.const_get(camelized_key) rescue base_class
|
61
|
-
end
|
109
|
+
private
|
62
110
|
|
63
111
|
def property_base_class
|
64
112
|
Vobject::Property
|
@@ -68,8 +116,11 @@ class Vobject::Component
|
|
68
116
|
Vobject::Component
|
69
117
|
end
|
70
118
|
|
119
|
+
def parameter_base_class
|
120
|
+
Vobject::Parameter
|
121
|
+
end
|
122
|
+
|
71
123
|
def raise_invalid_initialization
|
72
124
|
raise "vObject component initialization failed"
|
73
125
|
end
|
74
|
-
|
75
126
|
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module Vobject
|
2
|
+
class Parameter
|
3
|
+
attr_accessor :param_name, :value, :multiple, :norm
|
4
|
+
|
5
|
+
def <=>(another)
|
6
|
+
self.to_norm <=> another.to_norm
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(key, options)
|
10
|
+
self.param_name = key
|
11
|
+
if options.class == Array
|
12
|
+
self.multiple = []
|
13
|
+
options.each do |v|
|
14
|
+
multiple << parameter_base_class.new(key, v)
|
15
|
+
self.param_name = key
|
16
|
+
end
|
17
|
+
else
|
18
|
+
self.value = options
|
19
|
+
end
|
20
|
+
norm = nil
|
21
|
+
raise_invalid_initialization(key, name) if key != name
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
# we made param names have underscore instead of dash as symbols
|
26
|
+
line = param_name.to_s.tr("_", "-")
|
27
|
+
line << "="
|
28
|
+
if multiple
|
29
|
+
arr = []
|
30
|
+
multiple.each { |v| arr << to_s_line(v.value.to_s) }
|
31
|
+
line << arr.join(",")
|
32
|
+
else
|
33
|
+
line << to_s_line(value.to_s)
|
34
|
+
end
|
35
|
+
line
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_s_line(val)
|
39
|
+
# RFC 6868
|
40
|
+
val = val.to_s.gsub(/\^/, "^^").gsub(/\n/, "^n").gsub(/"/, "^'")
|
41
|
+
if val =~ /[:;,]/
|
42
|
+
val = '"' + val + '"'
|
43
|
+
end
|
44
|
+
val
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_norm
|
48
|
+
if norm.nil?
|
49
|
+
line = param_name.to_s.tr("_", "-").upcase
|
50
|
+
line << "="
|
51
|
+
if multiple
|
52
|
+
arr = []
|
53
|
+
multiple.sort.each { |v| arr << to_norm_line(v.value) }
|
54
|
+
line << arr.join(",")
|
55
|
+
else
|
56
|
+
line << to_norm_line(value)
|
57
|
+
end
|
58
|
+
norm = line
|
59
|
+
end
|
60
|
+
norm
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_norm_line(val)
|
64
|
+
# RFC 6868
|
65
|
+
val = val.to_s.gsub(/\^/, "^^").gsub(/\n/, "^n").gsub(/"/, "^'")
|
66
|
+
#if val =~ /[:;,]/
|
67
|
+
val = '"' + val + '"'
|
68
|
+
#end
|
69
|
+
val
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_hash
|
73
|
+
if multiple
|
74
|
+
val = []
|
75
|
+
multiple.each do |c|
|
76
|
+
val << c.value
|
77
|
+
end
|
78
|
+
{ param_name => val }
|
79
|
+
else
|
80
|
+
{ param_name => value }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def name
|
87
|
+
param_name
|
88
|
+
end
|
89
|
+
|
90
|
+
def parse_value(value)
|
91
|
+
parse_method = :"parse_#{value_type}_value"
|
92
|
+
parse_method = respond_to?(parse_method, true) ? parse_method : :parse_text_value
|
93
|
+
send(parse_method, value)
|
94
|
+
end
|
95
|
+
|
96
|
+
def parse_text_value(value)
|
97
|
+
value
|
98
|
+
end
|
99
|
+
|
100
|
+
def value_type
|
101
|
+
(params || {})[:VALUE] || default_value_type
|
102
|
+
end
|
103
|
+
|
104
|
+
def default_value_type
|
105
|
+
"text"
|
106
|
+
end
|
107
|
+
|
108
|
+
def parameter_base_class
|
109
|
+
Vobject::Parameter
|
110
|
+
end
|
111
|
+
|
112
|
+
def raise_invalid_initialization(key, name)
|
113
|
+
raise "vObject property initialization failed (#{key}, #{name})"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|