openehr 2.0.2 → 2.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3ee9bac169579e3747a7620ea835317f3c58c6eef05782d7ec3631c324bb4128
4
- data.tar.gz: 51db4fef2f14ea1de6a472e2c3a876e4c48670d1a57c9385874c9ecd8623b8a6
3
+ metadata.gz: 9e728b70dac1326f832dd44e631442ae3e9ed8b3a3c81a2b5300c23e01a9068e
4
+ data.tar.gz: 0003101647c193f7d35d575a3eef1a92a8e34038a849719a0598e34109f92a52
5
5
  SHA512:
6
- metadata.gz: dadd78aeb5e2ddbcaf042468ad6f25ac48e50887f78d9abe6513f2574d017451418fc43607529861fcc0f29a9fd0ba033ec7bfc9cac72ed3305b1c62683ec51d
7
- data.tar.gz: b25f5f631f71b01d3de6941ec1bd8261c40a14366ac7f0ef43e333a41039a7b53e7a2d1172dc04093a4630ea38644089df1e433c16caa31aae82c3107d9ca888
6
+ metadata.gz: 334d9390f1e59a2a68a812fda1c946ddf3a74504b4234f6363dddee9e42d8763b01d8bbee50fed8c894318c4bec794b4ba743310961e4ba482164ccf9ec660e7
7
+ data.tar.gz: 611283bb569b4bc0672a502d09b6c485db8ca47131dd8393fdb6ac67589bbdfeb305d0a98a628997a6091ffd6dda03d57695560a61308104f96c06f7e95a9c98
@@ -286,7 +286,7 @@ module OpenEHR
286
286
  end
287
287
 
288
288
  class CComplexObject < CDefinedObject
289
- attr_accessor :attributes
289
+ attr_reader :attributes
290
290
 
291
291
  def initialize(args = { })
292
292
  super
@@ -254,8 +254,8 @@ module OpenEHR
254
254
  end
255
255
 
256
256
  def to_days
257
- days = nilthenzero(@year)*TimeDefinitions::NOMINAL_DAYS_IN_YEAR +
258
- nilthenzero(@month)*TimeDefinitions::NOMINAL_DAYS_IN_MONTH +
257
+ days = (nilthenzero(@year)*TimeDefinitions::NOMINAL_DAYS_IN_YEAR) +
258
+ (nilthenzero(@month)*TimeDefinitions::NOMINAL_DAYS_IN_MONTH) +
259
259
  nilthenzero(@day)
260
260
  return days
261
261
  end
@@ -406,7 +406,7 @@ module OpenEHR
406
406
  end
407
407
 
408
408
  def to_second
409
- second = (nilthenzero(@hour)*60 + nilthenzero(@minute))*60 +
409
+ second = (((nilthenzero(@hour)*60) + nilthenzero(@minute))*60) +
410
410
  nilthenzero(@second) +
411
411
  nilthenzero(@fractional_second)
412
412
  return second
@@ -472,18 +472,21 @@ module OpenEHR
472
472
  end
473
473
  # A timezone is optional in ISO 8601; its absence does not make an
474
474
  # otherwise-valid time invalid.
475
- unless tz.nil?
476
- timezone = Timezone.new(tz)
477
- if timezone.hour < 0 or timezone.hour >= HOURS_IN_DAY
478
- return false
479
- end
480
- if timezone.minute < 0 or timezone.minute >= MINUTES_IN_HOUR
481
- return false
482
- end
483
- end
475
+ return false unless valid_timezone_part?(tz)
476
+
484
477
  return true
485
478
  end
486
479
  end
480
+
481
+ def self.valid_timezone_part?(tz)
482
+ return true if tz.nil?
483
+
484
+ timezone = Timezone.new(tz)
485
+ return false if timezone.hour < 0 or timezone.hour >= HOURS_IN_DAY
486
+ return false if timezone.minute < 0 or timezone.minute >= MINUTES_IN_HOUR
487
+
488
+ true
489
+ end
487
490
  end # end of ISO8601_TIME
488
491
 
489
492
  module ISO8601DateTimeModule
@@ -571,7 +574,7 @@ module OpenEHR
571
574
 
572
575
  protected
573
576
  def magnitude
574
- return self.to_days*HOURS_IN_DAY*MINUTES_IN_HOUR*SECONDS_IN_MINUTE +
577
+ return (self.to_days*HOURS_IN_DAY*MINUTES_IN_HOUR*SECONDS_IN_MINUTE) +
575
578
  self.to_second
576
579
  end
577
580
  end
@@ -719,11 +722,11 @@ module OpenEHR
719
722
  end
720
723
 
721
724
  def to_seconds
722
- days = nilthenzero(@years)*TimeDefinitions::DAYS_IN_YEAR +
723
- nilthenzero(@months)*TimeDefinitions::DAYS_IN_MONTH +
724
- nilthenzero(@weeks)*TimeDefinitions::DAYS_IN_WEEK +
725
+ days = (nilthenzero(@years)*TimeDefinitions::DAYS_IN_YEAR) +
726
+ (nilthenzero(@months)*TimeDefinitions::DAYS_IN_MONTH) +
727
+ (nilthenzero(@weeks)*TimeDefinitions::DAYS_IN_WEEK) +
725
728
  nilthenzero(@days)
726
- seconds_with_fractional = (((days*TimeDefinitions::HOURS_IN_DAY + nilthenzero(@hours))*TimeDefinitions::MINUTES_IN_HOUR)+nilthenzero(@minutes))*TimeDefinitions::SECONDS_IN_MINUTE +
729
+ seconds_with_fractional = (((((days*TimeDefinitions::HOURS_IN_DAY) + nilthenzero(@hours))*TimeDefinitions::MINUTES_IN_HOUR)+nilthenzero(@minutes))*TimeDefinitions::SECONDS_IN_MINUTE) +
727
730
  nilthenzero(@seconds) +
728
731
  @fractional_second.to_f
729
732
  return negative? ? -seconds_with_fractional : seconds_with_fractional
@@ -8,10 +8,6 @@ module OpenEHR
8
8
  class ADLParser < ::OpenEHR::Parser::Base
9
9
  Treetop.load(File.join(File.dirname(__FILE__), 'adl_grammar.tt'))
10
10
 
11
- def initialize(filename)
12
- super
13
- end
14
-
15
11
  def parse(validate: false)
16
12
  archetype.tap do |a|
17
13
  ArchetypeValidator.new(a).validate! if validate
@@ -31,10 +31,6 @@ module OpenEHR
31
31
  '/template/description/other_details'
32
32
  DEFINITION_PATH = '/template/definition'
33
33
  OCCURRENCE_PATH = '/occurrences'
34
-
35
- def initialize(filename)
36
- super(filename)
37
- end
38
34
 
39
35
  def parse
40
36
  @opt = Nokogiri::XML::Document.parse(File.open(@filename))
@@ -194,8 +194,8 @@ module OpenEHR
194
194
  end
195
195
 
196
196
  class Attestation < AuditDetails
197
- attr_reader :reason
198
- attr_accessor :proof, :attested_view, :is_pending, :items
197
+ attr_reader :reason, :items
198
+ attr_accessor :proof, :attested_view, :is_pending
199
199
 
200
200
  def initialize(args = { })
201
201
  super(args)
@@ -1,4 +1,3 @@
1
- require 'set'
2
1
 
3
2
  module OpenEHR
4
3
  module RM
@@ -2,7 +2,6 @@
2
2
  # ItemStructure module
3
3
  # http://www.openehr.org/uml/release-1.0.1/Browsable/_9_0_76d0249_1109346709572_859750_3810Report.html
4
4
  # refs #54
5
- require 'set'
6
5
 
7
6
  require_relative '../data_structures'
8
7
  require_relative 'item_structure/representation'
@@ -25,20 +25,11 @@ module OpenEHR
25
25
  end
26
26
 
27
27
  class DvBoolean < DataValue
28
- def initialize(args)
29
- super(args)
30
- end
31
-
32
28
  def value=(value)
33
29
  raise ArgumentError, "value must not be nil" if value.nil?
34
- if value == true
35
- @value = true
36
- elsif value == false
37
- @value = false
38
- elsif /TRUE/i =~ value
39
- @value = true
40
- elsif /FALSE/i =~ value
41
- @value = false
30
+ case value
31
+ when true, /TRUE/i then @value = true
32
+ when false, /FALSE/i then @value = false
42
33
  end
43
34
  end
44
35
 
@@ -37,10 +37,10 @@ module OpenEHR
37
37
  @charset = charset
38
38
  end
39
39
 
40
- private
41
-
42
40
  CHARSET_LIST_PATH = File.expand_path('charset.lst', __dir__)
43
41
 
42
+ private
43
+
44
44
  def charset_valid?(charset)
45
45
  result = false
46
46
  File.open(CHARSET_LIST_PATH) do |file|
@@ -55,20 +55,8 @@ module OpenEHR
55
55
  else
56
56
  past, future = self, other
57
57
  end
58
- year, month, day = 0, 0, 0
59
- if (future.day >= past.day)
60
- day = future.day - past.day
61
- else
62
- month = -1
63
- previous_month = future.month - 1
64
- if previous_month == 0
65
- previous_month = 12
66
- end
67
- day = DAYS_IN_MONTH[previous_month] + future.day - past.day
68
- if leapyear?(future.year) && (previous_month == 2)
69
- day += 1
70
- end
71
- end
58
+ year = 0
59
+ month, day = day_borrow(past, future)
72
60
  week = day / 7
73
61
  if (future.month >= past.month)
74
62
  month += future.month - past.month
@@ -82,11 +70,26 @@ module OpenEHR
82
70
  end
83
71
  year += future.year - past.year
84
72
  return DvDuration.new(:value =>
85
- 'P' + year.to_s + 'Y' + month.to_s + 'M' +
73
+ 'P' + year.to_s + 'Y' + month.to_s + 'M' +
86
74
  week.to_s + 'W' + day.to_s + 'D')
87
75
  end
76
+
77
+ private
78
+
79
+ # Returns [month_adjustment, day] for diff: when future's
80
+ # day-of-month is behind past's, a month is borrowed from
81
+ # future's calendar to make day non-negative.
82
+ def day_borrow(past, future)
83
+ return [0, future.day - past.day] if future.day >= past.day
84
+
85
+ previous_month = future.month - 1
86
+ previous_month = 12 if previous_month == 0
87
+ day = DAYS_IN_MONTH[previous_month] + future.day - past.day
88
+ day += 1 if leapyear?(future.year) && previous_month == 2
89
+ [-1, day]
90
+ end
88
91
  end
89
-
92
+
90
93
  class DvTime < DvTemporal
91
94
  include OpenEHR::AssumedLibraryTypes::ISO8601TimeModule
92
95
 
@@ -104,19 +107,19 @@ module OpenEHR
104
107
  if @fractional_second.nil? && @second.nil? && @minute.nil?
105
108
  return @hour * 60 * 60
106
109
  elsif @fractional_second.nil? && @second.nil?
107
- return @hour * 60 * 60 + @minute * 60
110
+ return (@hour * 60 * 60) + (@minute * 60)
108
111
  elsif @fractional_second.nil?
109
- return @hour * 60 * 60 + @minute * 60 + @second
112
+ return (@hour * 60 * 60) + (@minute * 60) + @second
110
113
  else
111
- return @hour*60*60+@minute* 60 + @second + @fractional_second
114
+ return (@hour*60*60)+(@minute* 60) + @second + @fractional_second
112
115
  end
113
116
  end
114
117
 
115
118
  def diff(other)
116
119
  diff = (other.magnitude - self.magnitude).abs
117
120
  hour = (diff / 60 / 60).to_i
118
- minute = ((diff - hour*60*60)/60).to_i
119
- second = (diff - hour * 60 * 60 - minute * 60).to_i
121
+ minute = ((diff - (hour*60*60))/60).to_i
122
+ second = (diff - (hour * 60 * 60) - (minute * 60)).to_i
120
123
  fractional_second = ((diff - diff.to_i)*1000000.0).to_i/1000000.0
121
124
  str = 'P0Y0M0W0DT' + hour.to_s + 'H' +
122
125
  minute.to_s + 'M' + second.to_s
@@ -156,11 +159,11 @@ module OpenEHR
156
159
  minute += @timezone.minute
157
160
  end
158
161
  end
159
- seconds = (((@year * 365.24 +
160
- @month * 30.42 +
161
- @day) * 24 +
162
- hour) * 60 +
163
- minute) * 60 + @second
162
+ seconds = (((((((@year * 365.24) +
163
+ (@month * 30.42) +
164
+ @day) * 24) +
165
+ hour) * 60) +
166
+ minute) * 60) + @second
164
167
  if @fractional_second.nil?
165
168
  return seconds
166
169
  else
@@ -168,6 +171,9 @@ module OpenEHR
168
171
  end
169
172
  end
170
173
 
174
+ # rubocop:disable Metrics/AbcSize -- dense calendar arithmetic; refactoring
175
+ # without broader leap-year/borrow coverage (only 1 example exercises this
176
+ # method) is riskier than the lint value gained
171
177
  def diff(other)
172
178
  if self.magnitude >= other.magnitude
173
179
  past, future = other, self
@@ -183,8 +189,8 @@ module OpenEHR
183
189
  end
184
190
  date_duration = past_date.diff(future_date)
185
191
  hour = (time_diff / 60 / 60).to_i
186
- minute = ((time_diff - hour*60*60)/60).to_i
187
- second = (time_diff - hour * 60 * 60 - minute * 60).to_i
192
+ minute = ((time_diff - (hour*60*60))/60).to_i
193
+ second = (time_diff - (hour * 60 * 60) - (minute * 60)).to_i
188
194
  str = date_duration.value + 'T' + hour.to_s + 'H' +
189
195
  minute.to_s + 'M' + second.to_s
190
196
  if @fractional_second.nil?
@@ -196,6 +202,7 @@ module OpenEHR
196
202
  fractional_second.to_s[1..-1] + 'S')
197
203
  end
198
204
  end
205
+ # rubocop:enable Metrics/AbcSize
199
206
 
200
207
  private
201
208
  def split_date_time(date_time)
@@ -11,7 +11,8 @@ module OpenEHR
11
11
 
12
12
  class DvOrdered < OpenEHR::RM::DataTypes::Basic::DataValue
13
13
  include Comparable
14
- attr_accessor :normal_range, :other_reference_ranges, :normal_status
14
+ attr_accessor :normal_range, :normal_status
15
+ attr_reader :other_reference_ranges
15
16
 
16
17
  def initialize(args = {})
17
18
  super(args)
@@ -1,5 +1,6 @@
1
1
  # This module is related to the ticket #47
2
2
  require_relative 'basic'
3
+ require_relative 'quantity/date_time'
3
4
 
4
5
  module OpenEHR
5
6
  module RM
@@ -8,19 +9,24 @@ module OpenEHR
8
9
  class DvTimeSpecification < OpenEHR::RM::DataTypes::Basic::DataValue
9
10
  attr_reader :value
10
11
 
11
- def initialize(value)
12
- self.value=(value)
13
- end
14
-
15
12
  def value=(value)
16
13
  raise ArgumentError, 'value must be not nil' if value.nil?
14
+ unless value.respond_to?(:formalism) && value.respond_to?(:value)
15
+ raise ArgumentError, 'value must be a DV_PARSABLE'
16
+ end
17
17
  @value = value
18
18
  end
19
-
19
+
20
20
  def calendar_alignment
21
21
  raise NotImplementedError, "calendar_alignment must be implemented"
22
22
  end
23
- alias calender_alignment calendar_alignment
23
+
24
+ # Legacy misspelling, deliberately kept (pinned by spec). Defined
25
+ # as a delegating method rather than `alias` so a subclass
26
+ # override of calendar_alignment is still reached through it.
27
+ def calender_alignment
28
+ calendar_alignment
29
+ end
24
30
 
25
31
  def event_alignment
26
32
  raise NotImplementedError, "event_alignment must be implemented"
@@ -35,39 +41,107 @@ module OpenEHR
35
41
  # because I could not obtain HL7 specification related them.
36
42
 
37
43
  class DvGeneralTimeSpecification < DvTimeSpecification
38
- attr_reader :value
39
- def initialize(value)
40
- super(value)
41
- end
44
+ FORMALISM = 'HL7:GTS'
45
+
42
46
  def value=(value)
43
- raise ArgumentError, "value is not valied" unless value.formalism.is_equal?('HL7:GTS')
44
- @value = value
45
- end
46
- private
47
- def value_valid(value)
47
+ unless value.respond_to?(:formalism) && value.formalism == FORMALISM
48
+ raise ArgumentError, "formalism must be #{FORMALISM}"
49
+ end
50
+ super
48
51
  end
52
+ # calendar_alignment / event_alignment / institution_specified
53
+ # remain NotImplementedError (inherited from DvTimeSpecification):
54
+ # deriving them requires parsing the full HL7 GTS set-algebra
55
+ # (union/intersection/exclusion of interval sets), which is
56
+ # explicitly out of scope here.
49
57
  end
50
58
 
51
59
  class DvPeriodicTimeSpecification < DvTimeSpecification
52
- attr_reader :value, :calender_alignment, :event_alingment, :period
53
- def initialize(value)
54
- value_valid(value)
55
- super(value)
56
- end
60
+ PIVL_FORMALISM = 'HL7:PIVL'
61
+ EIVL_FORMALISM = 'HL7:EIVL'
62
+
63
+ # Single-literal PIVL: [phase_low(;phase_high)?]/(period)@ALIGN? IST?
64
+ # e.g. "[200004181100;200004181110]/(7d)@DW IST"
65
+ PIVL_PATTERN = %r{\A\[(?<phase_low>\d+)(?:;(?<phase_high>\d+))?\]/
66
+ \((?<period>\d+(?:\.\d+)?)(?<unit>[a-z]+)\)
67
+ (?:@(?<alignment>[A-Z]{2}))?(?<ist>\ ?IST)?\z}x
68
+
69
+ # Single-literal EIVL: EVENT([+-]offset)? e.g. "ACM+10min"
70
+ EIVL_PATTERN = /\A(?<event>[A-Z]+)(?:(?<sign>[+-])(?<offset>\d+(?:\.\d+)?)(?<unit>[a-z]+))?\z/
71
+
72
+ # HL7 CalendarCycle codes (DW=day of week, HD=hour of day, ...)
73
+ CALENDAR_CYCLE_CODES = %w[CY MY CM CW WY DM CD DY DW HD CH NH CN SN CS].freeze
74
+ # HL7 TimingEvent codes (HS=bedtime, ACM=before breakfast, ...)
75
+ TIMING_EVENT_CODES = %w[HS WAKE C CM CD CV AC ACM ACD ACV PC PCM PCD PCV].freeze
76
+ # HL7 physical-quantity time units -> ISO8601 duration templates
77
+ PERIOD_UNIT_TO_ISO8601 = { 's' => 'PT%sS', 'min' => 'PT%sM', 'h' => 'PT%sH',
78
+ 'd' => 'P%sD', 'wk' => 'P%sW', 'mo' => 'P%sM',
79
+ 'a' => 'P%sY' }.freeze
80
+
81
+ attr_reader :period, :calendar_alignment, :event_alignment
82
+
57
83
  def value=(value)
58
- unless value.formalism.is_equal('HL7:PIVL') or value.formalism.is_equal('HL7:EIVL')
59
- raise ArgumentError, "value is not valid"
84
+ unless value.respond_to?(:formalism) &&
85
+ [PIVL_FORMALISM, EIVL_FORMALISM].include?(value.formalism)
86
+ raise ArgumentError, "formalism must be #{PIVL_FORMALISM} or #{EIVL_FORMALISM}"
87
+ end
88
+ if value.formalism == PIVL_FORMALISM
89
+ parse_pivl(value.value)
90
+ else
91
+ parse_eivl(value.value)
60
92
  end
61
- if value.formalism('HL7:PIVL')
62
- /^\[(\d+)\;?(\d+)?\]\/\((\d+\w+)\)(@(\w+?))?(IST)?$/ =~ value
63
- interval1, interval2, difference, allignment = $1, $2, $3, $5
93
+ super
94
+ end
95
+
96
+ def institution_specified
97
+ @institution_specified
98
+ end
99
+ alias institution_specified? institution_specified
100
+
101
+ private
102
+
103
+ def parse_pivl(raw)
104
+ match = PIVL_PATTERN.match(raw)
105
+ raise ArgumentError, 'value does not match HL7:PIVL syntax' unless match
106
+
107
+ unit = match[:unit]
108
+ unless PERIOD_UNIT_TO_ISO8601.key?(unit)
109
+ raise ArgumentError, "unknown HL7 PIVL period unit #{unit.inspect}"
64
110
  end
65
- if value
111
+
112
+ alignment = match[:alignment]
113
+ if alignment && !CALENDAR_CYCLE_CODES.include?(alignment)
114
+ raise ArgumentError, "unknown HL7 CalendarCycle code #{alignment.inspect}"
66
115
  end
116
+
117
+ @period = DataTypes::Quantity::DateTime::DvDuration.new(:value => period_from(match[:period], unit))
118
+ @calendar_alignment = alignment
119
+ @event_alignment = nil
120
+ @institution_specified = !match[:ist].nil?
67
121
  end
68
122
 
69
- def institution_specified?
123
+ def parse_eivl(raw)
124
+ match = EIVL_PATTERN.match(raw)
125
+ raise ArgumentError, 'value does not match HL7:EIVL syntax' unless match
126
+
127
+ event = match[:event]
128
+ unless TIMING_EVENT_CODES.include?(event)
129
+ raise ArgumentError, "unknown HL7 TimingEvent code #{event.inspect}"
130
+ end
131
+
132
+ unit = match[:unit]
133
+ if unit && !PERIOD_UNIT_TO_ISO8601.key?(unit)
134
+ raise ArgumentError, "unknown HL7 EIVL offset unit #{unit.inspect}"
135
+ end
136
+
137
+ @event_alignment = event
138
+ @calendar_alignment = nil
139
+ @period = nil
140
+ @institution_specified = false
141
+ end
70
142
 
143
+ def period_from(quantity, unit)
144
+ format(PERIOD_UNIT_TO_ISO8601[unit], quantity)
71
145
  end
72
146
  end
73
147
  end
@@ -31,10 +31,6 @@ module OpenEHR
31
31
  module DataTypes
32
32
  module URI
33
33
  class DvUri < OpenEHR::RM::DataTypes::Basic::DataValue
34
- def initialize(args = {})
35
- self.value = args[:value]
36
- end
37
-
38
34
  def value
39
35
  @value
40
36
  end
@@ -69,10 +65,6 @@ module OpenEHR
69
65
  end
70
66
 
71
67
  class DvEhrUri < DvUri
72
- def initialize(value)
73
- super
74
- end
75
-
76
68
  def value=(value)
77
69
  raise ArgumentError, "scheme must be ehr" if !(value =~ /^ehr/i)
78
70
  parse(value)
@@ -277,6 +277,24 @@ module OpenEHR
277
277
  end
278
278
  end
279
279
 
280
+ class DvTimeSpecificationFactory
281
+ def self.create(param)
282
+ DataTypes::TimeSpecification::DvTimeSpecification.new(param)
283
+ end
284
+ end
285
+
286
+ class DvGeneralTimeSpecificationFactory
287
+ def self.create(param)
288
+ DataTypes::TimeSpecification::DvGeneralTimeSpecification.new(param)
289
+ end
290
+ end
291
+
292
+ class DvPeriodicTimeSpecificationFactory
293
+ def self.create(param)
294
+ DataTypes::TimeSpecification::DvPeriodicTimeSpecification.new(param)
295
+ end
296
+ end
297
+
280
298
  class ObservationFactory
281
299
  def self.create(param)
282
300
  Composition::Content::Entry::Observation.new(param)
@@ -5,7 +5,9 @@ module OpenEHR
5
5
  module RM
6
6
  module Security
7
7
  class AccessControlSettings
8
-
8
+ # Deliberate stub: openEHR RM 1.0.1 Security package class (see
9
+ # UML reference above); no behavior is specified for it beyond
10
+ # existence.
9
11
  end
10
12
  end
11
13
  end
@@ -1,4 +1,3 @@
1
- require 'set'
2
1
  require 'active_support/core_ext/string/inflections'
3
2
 
4
3
  module OpenEHR
@@ -1,66 +1,39 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'base'
2
4
 
3
5
  module OpenEHR
4
6
  module Serializer
5
7
  class ADLSerializer < BaseSerializer
6
8
  def header
7
- hd = 'archetype'
9
+ hd = +'archetype'
8
10
  unless @archetype.adl_version.nil?
9
11
  hd << " (adl_version = #{@archetype.adl_version})"
10
12
  end
11
- hd << NL+INDENT + "#{@archetype.archetype_id.value}"+NL*2
12
- hd << 'concept'+NL+ INDENT+"[#{@archetype.concept}]"+NL
13
- hd << NL+'language'+NL+INDENT+'original_language = <['+
13
+ hd << (NL+INDENT + "#{@archetype.archetype_id.value}"+(NL*2))
14
+ hd << ('concept'+NL+ INDENT+"[#{@archetype.concept}]"+NL)
15
+ hd << (NL+'language'+NL+INDENT+'original_language = <['+
14
16
  @archetype.original_language.terminology_id.value+'::'+
15
- @archetype.original_language.code_string+']>'+NL
17
+ @archetype.original_language.code_string+']>'+NL)
16
18
  return hd
17
19
  end
18
20
 
19
21
  def description
20
- desc = ''
22
+ desc = +''
21
23
  if @archetype.description
22
24
  ad = @archetype.description
23
- desc << 'description' + NL
24
- desc << INDENT + 'original_author = <' + NL
25
+ desc << ('description' + NL)
26
+ desc << (INDENT + 'original_author = <' + NL)
25
27
  ad.original_author.each do |k,v|
26
- desc << INDENT+INDENT+'["'+k+'"] = <"'+v+'">'+NL
28
+ desc << (INDENT+INDENT+'["'+k+'"] = <"'+v+'">'+NL)
27
29
  end
28
- desc << INDENT+'>'+NL
29
- desc << INDENT+'lifecycle_state = <"'+ad.lifecycle_state+'">'+NL
30
- desc << INDENT+'details = <'+NL
30
+ desc << (INDENT+'>'+NL)
31
+ desc << (INDENT+'lifecycle_state = <"'+ad.lifecycle_state+'">'+NL)
32
+ desc << (INDENT+'details = <'+NL)
31
33
  ad.details.each do |lang,item|
32
- desc << INDENT*2+'["'+lang+'"] = <'+NL
33
- desc << INDENT*3+'language = <['+
34
- item.language.terminology_id.value+'::'+
35
- item.language.code_string+']>'+NL
36
- desc << INDENT*3+'purpose = <"'+item.purpose+'">'+NL
37
- if item.keywords then
38
- desc << INDENT*3+'keywords = <'
39
- item.keywords.each do |word|
40
- desc << '"'+word+'",'
41
- end
42
- desc.chop! << '>'+NL
43
- end
44
- desc << INDENT*3+'use = <"'+item.use+'">'+NL if item.use
45
- desc << INDENT*3+'misuse = <"'+item.misuse+'">'+NL if item.misuse
46
- desc << INDENT*3+'copyright = <"'+item.copyright+'">'+NL if item.copyright
47
- if item.original_resource_uri
48
- desc << INDENT*3 + 'original_resource_uri = <'
49
- item.original_resource_uri.each do |k,v|
50
- desc << INDENT*4+'["'+k+'"] = <"'+v+'">'+NL
51
- end
52
- desc << INDENT*3+'>'+NL
53
- end
54
- if item.other_details
55
- desc << INDENT*3 + 'other_details = <'
56
- item.other_details.each do |k,v|
57
- desc << INDENT*4+'["'+k+'"] = <"'+v+'">'+NL
58
- end
59
- desc << INDENT*3+'>'+NL
60
- end
61
- desc << INDENT*2+'>'+NL
34
+ desc << description_details_item(lang, item)
62
35
  end
63
- desc << INDENT+'>'+NL
36
+ desc << (INDENT+'>'+NL)
64
37
  end
65
38
  return desc
66
39
  end
@@ -74,21 +47,7 @@ module OpenEHR
74
47
  ontology = 'ontology'+NL
75
48
  ontology << string_list_line('languages_available', ao.languages_available)
76
49
  ontology << string_list_line('terminologies_available', ao.terminologies_available)
77
- ontology << INDENT + 'term_definitions = <' + NL
78
- ao.term_definitions.each do |lang, items|
79
- ontology << INDENT*2 + "[\"#{lang}\"] = <" + NL
80
- ontology << INDENT*3 + 'items = <' + NL
81
- items.each do |code, item|
82
- ontology << INDENT*4 + "[\"#{code}\"] = <" + NL
83
- item.items.each do |name, desc|
84
- ontology << INDENT*5 + "#{name} = <\"#{desc}\">" + NL
85
- end
86
- ontology << INDENT*4 + '>'+NL
87
- end
88
- ontology << INDENT*3 + '>' + NL
89
- ontology << INDENT*2 + '>' + NL
90
- end
91
- ontology << INDENT + '>' + NL
50
+ ontology << term_definitions_block(ao.term_definitions)
92
51
  ontology << term_bindings_block(ao.term_bindings)
93
52
  ontology
94
53
  end
@@ -109,21 +68,80 @@ module OpenEHR
109
68
  INDENT + "#{keyword} = <" + values.map { |v| "\"#{v}\"" }.join(', ') + '>' + NL
110
69
  end
111
70
 
71
+ def description_details_item(lang, item)
72
+ block = (INDENT*2)+'["'+lang+'"] = <'+NL
73
+ block << description_language_line(item.language)
74
+ block << ((INDENT*3)+'purpose = <"'+item.purpose+'">'+NL)
75
+ block << description_keywords_line(item) if item.keywords
76
+ block << optional_field_line('use', item.use)
77
+ block << optional_field_line('misuse', item.misuse)
78
+ block << optional_field_line('copyright', item.copyright)
79
+ block << keyed_map_block('original_resource_uri', item.original_resource_uri) if item.original_resource_uri
80
+ block << keyed_map_block('other_details', item.other_details) if item.other_details
81
+ block << ((INDENT*2)+'>'+NL)
82
+ end
83
+
84
+ def description_language_line(language)
85
+ (INDENT*3)+'language = <['+
86
+ language.terminology_id.value+'::'+
87
+ language.code_string+']>'+NL
88
+ end
89
+
90
+ def optional_field_line(keyword, value)
91
+ return '' if value.nil?
92
+
93
+ (INDENT*3)+"#{keyword} = <\"#{value}\">"+NL
94
+ end
95
+
96
+ def description_keywords_line(item)
97
+ block = (INDENT*3)+'keywords = <'
98
+ item.keywords.each do |word|
99
+ block << ('"'+word+'",')
100
+ end
101
+ block.chop! << ('>'+NL)
102
+ end
103
+
104
+ def keyed_map_block(keyword, hash)
105
+ block = (INDENT*3) + "#{keyword} = <"
106
+ hash.each do |k,v|
107
+ block << ((INDENT*4)+'["'+k+'"] = <"'+v+'">'+NL)
108
+ end
109
+ block << ((INDENT*3)+'>'+NL)
110
+ end
111
+
112
+ def term_definitions_block(term_definitions)
113
+ block = INDENT + 'term_definitions = <' + NL
114
+ term_definitions.each do |lang, items|
115
+ block << ((INDENT*2) + "[\"#{lang}\"] = <" + NL)
116
+ block << ((INDENT*3) + 'items = <' + NL)
117
+ items.each do |code, item|
118
+ block << ((INDENT*4) + "[\"#{code}\"] = <" + NL)
119
+ item.items.each do |name, desc|
120
+ block << ((INDENT*5) + "#{name} = <\"#{desc}\">" + NL)
121
+ end
122
+ block << ((INDENT*4) + '>'+NL)
123
+ end
124
+ block << ((INDENT*3) + '>' + NL)
125
+ block << ((INDENT*2) + '>' + NL)
126
+ end
127
+ block << (INDENT + '>' + NL)
128
+ end
129
+
112
130
  def term_bindings_block(term_bindings)
113
131
  return '' if term_bindings.nil? || term_bindings.empty?
114
132
 
115
133
  block = INDENT + 'term_bindings = <' + NL
116
134
  term_bindings.each do |terminology, codes|
117
- block << INDENT*2 + "[\"#{terminology}\"] = <" + NL
118
- block << INDENT*3 + 'items = <' + NL
135
+ block << ((INDENT*2) + "[\"#{terminology}\"] = <" + NL)
136
+ block << ((INDENT*3) + 'items = <' + NL)
119
137
  codes.each do |code, bindings|
120
138
  code_phrase = Array(bindings).first
121
- block << INDENT*4 + "[\"#{code}\"] = <[#{code_phrase.terminology_id.value}::#{code_phrase.code_string}]>" + NL
139
+ block << ((INDENT*4) + "[\"#{code}\"] = <[#{code_phrase.terminology_id.value}::#{code_phrase.code_string}]>" + NL)
122
140
  end
123
- block << INDENT*3 + '>' + NL
124
- block << INDENT*2 + '>' + NL
141
+ block << ((INDENT*3) + '>' + NL)
142
+ block << ((INDENT*2) + '>' + NL)
125
143
  end
126
- block << INDENT + '>' + NL
144
+ block << (INDENT + '>' + NL)
127
145
  end
128
146
 
129
147
  # Recursive cADL emitter for a single C_OBJECT node, dispatching
@@ -151,12 +169,12 @@ module OpenEHR
151
169
  head + ' matches {*}' + NL
152
170
  else
153
171
  body = node.attributes.map { |a| emit_c_attribute(a, depth + 1) }.join
154
- head + ' matches {' + NL + body + INDENT*depth + '}' + NL
172
+ head + ' matches {' + NL + body + (INDENT*depth) + '}' + NL
155
173
  end
156
174
  end
157
175
 
158
176
  def complex_object_head(node, depth)
159
- head = INDENT*depth + node.rm_type_name
177
+ head = (INDENT*depth) + node.rm_type_name
160
178
  head += "[#{node.node_id}]" if node.node_id
161
179
  head += " occurrences matches {#{interval_literal(node.occurrences)}}" if show_interval?(node.occurrences)
162
180
  head
@@ -177,12 +195,12 @@ module OpenEHR
177
195
  head + " matches {#{inline_body(children.first)}}" + NL
178
196
  else
179
197
  body = children.map { |c| emit_c_object(c, depth + 1) }.join
180
- head + ' matches {' + NL + body + INDENT*depth + '}' + NL
198
+ head + ' matches {' + NL + body + (INDENT*depth) + '}' + NL
181
199
  end
182
200
  end
183
201
 
184
202
  def attribute_head(attribute, depth)
185
- head = INDENT*depth + attribute.rm_attribute_name
203
+ head = (INDENT*depth) + attribute.rm_attribute_name
186
204
  head += " existence matches {#{interval_literal(attribute.existence)}}" if show_interval?(attribute.existence)
187
205
  head += " cardinality matches {#{cardinality_literal(attribute.cardinality)}}" if attribute.is_a?(CMultipleAttribute)
188
206
  head
@@ -208,30 +226,30 @@ module OpenEHR
208
226
  end
209
227
 
210
228
  def emit_archetype_slot(node, depth)
211
- head = INDENT*depth + 'allow_archetype ' + node.rm_type_name
229
+ head = (INDENT*depth) + 'allow_archetype ' + node.rm_type_name
212
230
  head += "[#{node.node_id}]" if node.node_id
213
231
  head += " occurrences matches {#{interval_literal(node.occurrences)}}" if show_interval?(node.occurrences)
214
232
  lines = [head + ' matches {' + NL]
215
233
  lines << assertion_block(node.includes, 'include', depth + 1)
216
234
  lines << assertion_block(node.excludes, 'exclude', depth + 1)
217
- lines << INDENT*depth + '}' + NL
235
+ lines << ((INDENT*depth) + '}' + NL)
218
236
  lines.join
219
237
  end
220
238
 
221
239
  def assertion_block(assertions, keyword, depth)
222
240
  return '' if assertions.nil?
223
241
 
224
- lines = [INDENT*depth + keyword + NL]
225
- assertions.each { |a| lines << INDENT*(depth+1) + a.string_expression + NL }
242
+ lines = [(INDENT*depth) + keyword + NL]
243
+ assertions.each { |a| lines << ((INDENT*(depth+1)) + a.string_expression + NL) }
226
244
  lines.join
227
245
  end
228
246
 
229
247
  def emit_internal_ref(node, depth)
230
- INDENT*depth + "use_node #{node.rm_type_name} #{node.target_path}" + NL
248
+ (INDENT*depth) + "use_node #{node.rm_type_name} #{node.target_path}" + NL
231
249
  end
232
250
 
233
251
  def emit_constraint_ref(node, depth)
234
- INDENT*depth + "[#{node.reference}]" + NL
252
+ (INDENT*depth) + "[#{node.reference}]" + NL
235
253
  end
236
254
 
237
255
  def primitive_body(item)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OpenEHR
2
4
  module Serializer
3
5
  NL = "\r\n"
@@ -1,5 +1,4 @@
1
1
  require 'json'
2
- require 'set'
3
2
 
4
3
  module OpenEHR
5
4
  module Serializer
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rexml/document'
2
4
  require 'builder'
3
5
  require_relative 'base'
@@ -6,7 +8,7 @@ module OpenEHR
6
8
  module Serializer
7
9
  class XMLSerializer < BaseSerializer
8
10
  def header
9
- header = ''
11
+ header = +''
10
12
  xml = Builder::XmlMarkup.new(:indent => 2, :target => header)
11
13
  xml.archetype_id do
12
14
  xml.value @archetype.archetype_id.value
@@ -22,7 +24,7 @@ module OpenEHR
22
24
  end
23
25
 
24
26
  def description
25
- desc = ''
27
+ desc = +''
26
28
  xml = Builder::XmlMarkup.new(:indent => 2, :target => desc)
27
29
  ad = @archetype.description
28
30
  if ad
@@ -66,7 +68,7 @@ module OpenEHR
66
68
  end
67
69
 
68
70
  def definition
69
- definition = ''
71
+ definition = +''
70
72
  xml = Builder::XmlMarkup.new(:indent => 2, :target => definition)
71
73
  xml.definition do
72
74
  emit_c_object_body(xml, @archetype.definition)
@@ -75,7 +77,7 @@ module OpenEHR
75
77
  end
76
78
 
77
79
  def ontology
78
- ontology = ''
80
+ ontology = +''
79
81
  ao = @archetype.ontology
80
82
  xml = Builder::XmlMarkup.new(:indent => 2, :target => ontology)
81
83
  xml.ontology do
@@ -1,3 +1,3 @@
1
1
  module OpenEHR
2
- VERSION = "2.0.2"
2
+ VERSION = "2.1.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openehr
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shinji KOBAYASHI
@@ -139,146 +139,6 @@ dependencies:
139
139
  - - ">="
140
140
  - !ruby/object:Gem::Version
141
141
  version: '0'
142
- - !ruby/object:Gem::Dependency
143
- name: rspec
144
- requirement: !ruby/object:Gem::Requirement
145
- requirements:
146
- - - ">="
147
- - !ruby/object:Gem::Version
148
- version: '0'
149
- type: :development
150
- prerelease: false
151
- version_requirements: !ruby/object:Gem::Requirement
152
- requirements:
153
- - - ">="
154
- - !ruby/object:Gem::Version
155
- version: '0'
156
- - !ruby/object:Gem::Dependency
157
- name: rspec-expectations
158
- requirement: !ruby/object:Gem::Requirement
159
- requirements:
160
- - - ">="
161
- - !ruby/object:Gem::Version
162
- version: '0'
163
- type: :development
164
- prerelease: false
165
- version_requirements: !ruby/object:Gem::Requirement
166
- requirements:
167
- - - ">="
168
- - !ruby/object:Gem::Version
169
- version: '0'
170
- - !ruby/object:Gem::Dependency
171
- name: rspec-collection_matchers
172
- requirement: !ruby/object:Gem::Requirement
173
- requirements:
174
- - - ">="
175
- - !ruby/object:Gem::Version
176
- version: '0'
177
- type: :development
178
- prerelease: false
179
- version_requirements: !ruby/object:Gem::Requirement
180
- requirements:
181
- - - ">="
182
- - !ruby/object:Gem::Version
183
- version: '0'
184
- - !ruby/object:Gem::Dependency
185
- name: guard
186
- requirement: !ruby/object:Gem::Requirement
187
- requirements:
188
- - - ">="
189
- - !ruby/object:Gem::Version
190
- version: '0'
191
- type: :development
192
- prerelease: false
193
- version_requirements: !ruby/object:Gem::Requirement
194
- requirements:
195
- - - ">="
196
- - !ruby/object:Gem::Version
197
- version: '0'
198
- - !ruby/object:Gem::Dependency
199
- name: guard-rspec
200
- requirement: !ruby/object:Gem::Requirement
201
- requirements:
202
- - - ">="
203
- - !ruby/object:Gem::Version
204
- version: '0'
205
- type: :development
206
- prerelease: false
207
- version_requirements: !ruby/object:Gem::Requirement
208
- requirements:
209
- - - ">="
210
- - !ruby/object:Gem::Version
211
- version: '0'
212
- - !ruby/object:Gem::Dependency
213
- name: simplecov
214
- requirement: !ruby/object:Gem::Requirement
215
- requirements:
216
- - - ">="
217
- - !ruby/object:Gem::Version
218
- version: '0'
219
- type: :development
220
- prerelease: false
221
- version_requirements: !ruby/object:Gem::Requirement
222
- requirements:
223
- - - ">="
224
- - !ruby/object:Gem::Version
225
- version: '0'
226
- - !ruby/object:Gem::Dependency
227
- name: libnotify
228
- requirement: !ruby/object:Gem::Requirement
229
- requirements:
230
- - - ">="
231
- - !ruby/object:Gem::Version
232
- version: '0'
233
- type: :development
234
- prerelease: false
235
- version_requirements: !ruby/object:Gem::Requirement
236
- requirements:
237
- - - ">="
238
- - !ruby/object:Gem::Version
239
- version: '0'
240
- - !ruby/object:Gem::Dependency
241
- name: rubocop
242
- requirement: !ruby/object:Gem::Requirement
243
- requirements:
244
- - - ">="
245
- - !ruby/object:Gem::Version
246
- version: '0'
247
- type: :development
248
- prerelease: false
249
- version_requirements: !ruby/object:Gem::Requirement
250
- requirements:
251
- - - ">="
252
- - !ruby/object:Gem::Version
253
- version: '0'
254
- - !ruby/object:Gem::Dependency
255
- name: meowcop
256
- requirement: !ruby/object:Gem::Requirement
257
- requirements:
258
- - - ">="
259
- - !ruby/object:Gem::Version
260
- version: '0'
261
- type: :development
262
- prerelease: false
263
- version_requirements: !ruby/object:Gem::Requirement
264
- requirements:
265
- - - ">="
266
- - !ruby/object:Gem::Version
267
- version: '0'
268
- - !ruby/object:Gem::Dependency
269
- name: better_errors
270
- requirement: !ruby/object:Gem::Requirement
271
- requirements:
272
- - - ">="
273
- - !ruby/object:Gem::Version
274
- version: '0'
275
- type: :development
276
- prerelease: false
277
- version_requirements: !ruby/object:Gem::Requirement
278
- requirements:
279
- - - ">="
280
- - !ruby/object:Gem::Version
281
- version: '0'
282
142
  description: This project is an implementation of the openEHR specification on Ruby.
283
143
  email: skoba@moss.gr.jp
284
144
  executables: []
@@ -373,7 +233,8 @@ files:
373
233
  homepage: http://openehr.jp
374
234
  licenses:
375
235
  - Apache 2.0
376
- metadata: {}
236
+ metadata:
237
+ rubygems_mfa_required: 'true'
377
238
  rdoc_options: []
378
239
  require_paths:
379
240
  - lib
@@ -388,7 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
388
249
  - !ruby/object:Gem::Version
389
250
  version: '0'
390
251
  requirements: []
391
- rubygems_version: 4.0.18
252
+ rubygems_version: 4.0.16
392
253
  specification_version: 4
393
254
  summary: Ruby implementation of the openEHR specification
394
255
  test_files: []