openhab-jrubyscripting 5.0.0.rc4 → 5.0.0.rc6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/lib/openhab/core/actions.rb +21 -9
  3. data/lib/openhab/core/dependency_tracking.rb +34 -0
  4. data/lib/openhab/core/entity_lookup.rb +132 -78
  5. data/lib/openhab/core/events/item_channel_link.rb +2 -2
  6. data/lib/openhab/core/events/item_command_event.rb +1 -1
  7. data/lib/openhab/core/events/item_event.rb +2 -2
  8. data/lib/openhab/core/events/item_state_changed_event.rb +1 -1
  9. data/lib/openhab/core/events/thing.rb +1 -1
  10. data/lib/openhab/core/items/accepted_data_types.rb +2 -2
  11. data/lib/openhab/core/items/contact_item.rb +1 -1
  12. data/lib/openhab/core/items/dimmer_item.rb +2 -2
  13. data/lib/openhab/core/items/generic_item.rb +45 -224
  14. data/lib/openhab/core/items/group_item.rb +5 -3
  15. data/lib/openhab/core/items/image_item.rb +2 -2
  16. data/lib/openhab/core/items/item.rb +219 -0
  17. data/lib/openhab/core/items/metadata/hash.rb +1 -1
  18. data/lib/openhab/core/items/metadata/namespace_hash.rb +1 -1
  19. data/lib/openhab/core/items/persistence.rb +19 -10
  20. data/lib/openhab/core/items/provider.rb +2 -2
  21. data/lib/openhab/core/items/proxy.rb +68 -7
  22. data/lib/openhab/core/items/registry.rb +6 -6
  23. data/lib/openhab/core/items/semantics/enumerable.rb +6 -6
  24. data/lib/openhab/core/items/semantics.rb +8 -7
  25. data/lib/openhab/core/items.rb +3 -2
  26. data/lib/openhab/core/provider.rb +14 -7
  27. data/lib/openhab/core/rules/registry.rb +2 -2
  28. data/lib/openhab/core/rules.rb +1 -1
  29. data/lib/openhab/core/script_handling.rb +6 -6
  30. data/lib/openhab/core/things/channel.rb +1 -1
  31. data/lib/openhab/core/things/channel_uid.rb +2 -2
  32. data/lib/openhab/core/things/item_channel_link.rb +2 -2
  33. data/lib/openhab/core/things/links/provider.rb +2 -2
  34. data/lib/openhab/core/things/profile_callback.rb +1 -1
  35. data/lib/openhab/core/things/registry.rb +1 -1
  36. data/lib/openhab/core/things/thing.rb +1 -1
  37. data/lib/openhab/core/timer.rb +21 -10
  38. data/lib/openhab/core/types/date_time_type.rb +4 -4
  39. data/lib/openhab/core/types/hsb_type.rb +2 -2
  40. data/lib/openhab/core/types/point_type.rb +1 -1
  41. data/lib/openhab/core/types/quantity_type.rb +1 -1
  42. data/lib/openhab/core/types.rb +1 -1
  43. data/lib/openhab/core/uid.rb +1 -1
  44. data/lib/openhab/core/value_cache.rb +188 -0
  45. data/lib/openhab/core.rb +57 -15
  46. data/lib/openhab/core_ext/between.rb +32 -0
  47. data/lib/openhab/core_ext/java/duration.rb +1 -0
  48. data/lib/openhab/core_ext/java/local_date.rb +1 -0
  49. data/lib/openhab/core_ext/java/local_time.rb +1 -0
  50. data/lib/openhab/core_ext/java/month.rb +12 -1
  51. data/lib/openhab/core_ext/java/month_day.rb +2 -0
  52. data/lib/openhab/core_ext/java/zoned_date_time.rb +4 -4
  53. data/lib/openhab/core_ext/ruby/date.rb +3 -1
  54. data/lib/openhab/core_ext/ruby/date_time.rb +1 -0
  55. data/lib/openhab/core_ext/ruby/symbol.rb +7 -0
  56. data/lib/openhab/core_ext/ruby/time.rb +1 -0
  57. data/lib/openhab/dsl/items/builder.rb +17 -10
  58. data/lib/openhab/dsl/items/ensure.rb +5 -5
  59. data/lib/openhab/dsl/items/timed_command.rb +5 -5
  60. data/lib/openhab/dsl/rules/automation_rule.rb +54 -40
  61. data/lib/openhab/dsl/rules/builder.rb +128 -79
  62. data/lib/openhab/dsl/rules/guard.rb +5 -5
  63. data/lib/openhab/dsl/rules/name_inference.rb +21 -2
  64. data/lib/openhab/dsl/rules/rule_triggers.rb +3 -3
  65. data/lib/openhab/dsl/rules/terse.rb +1 -0
  66. data/lib/openhab/dsl/rules/triggers/changed.rb +27 -24
  67. data/lib/openhab/dsl/rules/triggers/command.rb +6 -5
  68. data/lib/openhab/dsl/rules/triggers/conditions/duration.rb +3 -3
  69. data/lib/openhab/dsl/rules/triggers/cron/cron.rb +2 -2
  70. data/lib/openhab/dsl/rules/triggers/cron/cron_handler.rb +6 -6
  71. data/lib/openhab/dsl/rules/triggers/updated.rb +5 -5
  72. data/lib/openhab/dsl/rules/triggers/watch/watch_handler.rb +11 -12
  73. data/lib/openhab/dsl/things/builder.rb +73 -14
  74. data/lib/openhab/dsl/version.rb +2 -2
  75. data/lib/openhab/dsl.rb +45 -17
  76. data/lib/openhab/log.rb +5 -5
  77. data/lib/openhab/rspec/configuration.rb +5 -5
  78. data/lib/openhab/rspec/example_group.rb +1 -1
  79. data/lib/openhab/rspec/helpers.rb +5 -5
  80. data/lib/openhab/rspec/hooks.rb +19 -1
  81. data/lib/openhab/rspec/karaf.rb +13 -21
  82. data/lib/openhab/rspec/mocks/persistence_service.rb +15 -0
  83. data/lib/openhab/rspec/mocks/thing_handler.rb +2 -2
  84. data/lib/openhab/rspec/suspend_rules.rb +2 -1
  85. data/lib/openhab/yard/base_helper.rb +46 -0
  86. data/lib/openhab/yard/html_helper.rb +3 -3
  87. data/lib/openhab/yard/markdown_directive.rb +125 -0
  88. data/lib/openhab/yard/markdown_helper.rb +99 -0
  89. metadata +15 -7
data/lib/openhab/dsl.rb CHANGED
@@ -16,7 +16,7 @@ end
16
16
  require_relative "core_ext"
17
17
 
18
18
  #
19
- # Main OpenHAB Module
19
+ # Main openHAB Module
20
20
  #
21
21
  module OpenHAB
22
22
  #
@@ -69,7 +69,7 @@ module OpenHAB
69
69
  # The state being sent for `:state_from_item` and `:state_from_handler` events.
70
70
  # @yieldparam [Core::Things::ItemChannelLink] link
71
71
  # The link between the item and the channel, including its configuration.
72
- # @yieldparam [GenericItem] item The linked item.
72
+ # @yieldparam [Item] item The linked item.
73
73
  # @yieldparam [Core::Things::ChannelUID] channel_uid The linked channel.
74
74
  # @yieldparam [Hash] configuration The profile configuration.
75
75
  # @yieldparam [org.openhab.core.thing.profiles.ProfileContext] context The profile context.
@@ -106,6 +106,19 @@ module OpenHAB
106
106
 
107
107
  # @!group Object Access
108
108
 
109
+ #
110
+ # (see Core::ValueCache)
111
+ #
112
+ # @return [Core::ValueCache] the cache shared among all scripts and UI rules in all languages.
113
+ #
114
+ # @see Core::ValueCache ValueCache
115
+ #
116
+ # @since openHAB 3.4.0
117
+ #
118
+ def shared_cache
119
+ $sharedCache
120
+ end
121
+
109
122
  #
110
123
  # Fetches all rules from the rule registry.
111
124
  #
@@ -141,7 +154,7 @@ module OpenHAB
141
154
  #
142
155
  # @example
143
156
  # rule 'search for a suitable item' do
144
- # on_start
157
+ # on_load
145
158
  # triggered do
146
159
  # # Send ON to DimmerTest if it exists, otherwise send it to SwitchTest
147
160
  # (items['DimmerTest'] || items['SwitchTest'])&.on
@@ -153,9 +166,9 @@ module OpenHAB
153
166
  end
154
167
 
155
168
  #
156
- # Get all things known to OpenHAB
169
+ # Get all things known to openHAB
157
170
  #
158
- # @return [Core::Things::Registry] all Thing objects known to OpenHAB
171
+ # @return [Core::Things::Registry] all Thing objects known to openHAB
159
172
  #
160
173
  # @example
161
174
  # things.each { |thing| logger.info("Thing: #{thing.uid}")}
@@ -171,7 +184,7 @@ module OpenHAB
171
184
  end
172
185
 
173
186
  #
174
- # Provides access to timers created by {after}
187
+ # Provides access to timers created by {after after}
175
188
  #
176
189
  # @return [TimerManager]
177
190
  def timers
@@ -186,7 +199,8 @@ module OpenHAB
186
199
  # ### Reentrant Timers
187
200
  #
188
201
  # Timers with an id are reentrant by id. Reentrant means that when the same id is encountered,
189
- # the timer is rescheduled rather than creating a second new timer.
202
+ # the timer is rescheduled rather than creating a second new timer. Note that the timer will
203
+ # execute the block provided in the latest call.
190
204
  #
191
205
  # This removes the need for the usual boilerplate code to manually keep track of timer objects.
192
206
  #
@@ -194,7 +208,7 @@ module OpenHAB
194
208
  #
195
209
  # When a timer is cancelled, it will be removed from the object.
196
210
  #
197
- # Be sure that your ids are unique. For example, if you're using {GenericItem items} as your
211
+ # Be sure that your ids are unique. For example, if you're using {Item items} as your
198
212
  # ids, you either need to be sure you don't use the same item for multiple logical contexts,
199
213
  # or you need to make your id more specific, by doing something like embedding the item in
200
214
  # array with a symbol of the timer's purpose, like `[:vacancy, item]`. But also note that
@@ -221,7 +235,7 @@ module OpenHAB
221
235
  # logger.info("Timer Fired")
222
236
  # end
223
237
  #
224
- # @example Timers delegate methods to OpenHAB timer objects
238
+ # @example Timers delegate methods to openHAB timer objects
225
239
  # after 1.second do |timer|
226
240
  # logger.info("Timer is active? #{timer.active?}")
227
241
  # end
@@ -267,9 +281,21 @@ module OpenHAB
267
281
  # end
268
282
  #
269
283
  # @example Only create a new timer if it isn't already scheduled
270
- # after(1.minute, id: :foo, reschedule: false) do
271
- # logger.info("Timer fired")
272
- # end
284
+ # after(1.minute, id: :foo, reschedule: false) do
285
+ # logger.info("Timer fired")
286
+ # end
287
+ #
288
+ # @example Reentrant timers will execute the block from the most recent call
289
+ # # In the following example, if Item1 received a command, followed by Item2,
290
+ # # the timer will execute the block referring to Item2.
291
+ # rule "Execute The Most Recent Block" do
292
+ # received_command Item1, Item2
293
+ # run do |event|
294
+ # after(10.minutes, id: :common_timer) do
295
+ # logger.info "The latest command was received from #{event.item}"
296
+ # end
297
+ # end
298
+ # end
273
299
  #
274
300
  def after(duration, id: nil, reschedule: true, &block)
275
301
  raise ArgumentError, "Block is required" unless block
@@ -299,6 +325,8 @@ module OpenHAB
299
325
  # @example Create a time range
300
326
  # between('7am'..'12pm').cover?(LocalTime.now)
301
327
  #
328
+ # @see CoreExt::Between#between? #between?
329
+ #
302
330
  def between(range)
303
331
  raise ArgumentError, "Supplied object must be a range" unless range.is_a?(Range)
304
332
 
@@ -311,10 +339,10 @@ module OpenHAB
311
339
  # Store states of supplied items
312
340
  #
313
341
  # Takes one or more items and returns a map `{Item => State}` with the
314
- # current state of each item. It is implemented by calling OpenHAB's
342
+ # current state of each item. It is implemented by calling openHAB's
315
343
  # [events.storeStates()](https://www.openhab.org/docs/configuration/actions.html#event-bus-actions).
316
344
  #
317
- # @param [GenericItem] items Items to store states of.
345
+ # @param [Item] items Items to store states of.
318
346
  #
319
347
  # @return [Core::Items::StateStorage] item states
320
348
  #
@@ -601,7 +629,7 @@ module OpenHAB
601
629
  # Otherwise it's applied to all types.
602
630
  # @param [Hash] providers_by_type
603
631
  # A list of providers by type. Type can be `:items`, `:metadata`, `:things`, `:links`,
604
- # a {GenericItem} applying the provider to all metadata on that item, or a String or Symbol
632
+ # an {Item} applying the provider to all metadata on that item, or a String or Symbol
605
633
  # applying the provider to all metadata of that namespace.
606
634
  #
607
635
  # The provider can be a {org.openhab.core.common.registry.Provider Provider}, `:persistent`,
@@ -665,7 +693,7 @@ module OpenHAB
665
693
  thread_providers[type] = provider
666
694
  when Symbol, String
667
695
  (thread_providers[:metadata_namespaces] ||= {})[type.to_s] = provider
668
- when GenericItem
696
+ when Item
669
697
  (thread_providers[:metadata_items] ||= {})[type.name] = provider
670
698
  else
671
699
  raise ArgumentError, "#{type.inspect} is not provider type"
@@ -700,4 +728,4 @@ OpenHAB::Core::Items.import_into_global_namespace
700
728
  # Extend `main` with DSL methods
701
729
  singleton_class.include(OpenHAB::DSL)
702
730
 
703
- logger.debug "OpenHAB JRuby Scripting Library Version #{OpenHAB::DSL::VERSION} Loaded"
731
+ logger.debug "openHAB JRuby Scripting Library Version #{OpenHAB::DSL::VERSION} Loaded"
data/lib/openhab/log.rb CHANGED
@@ -6,7 +6,7 @@ module OpenHAB
6
6
  # rubocop:disable Layout/LineLength
7
7
 
8
8
  #
9
- # Provides access to the OpenHAB logging facilities using Ruby logging methods
9
+ # Provides access to the openHAB logging facilities using Ruby logging methods
10
10
  #
11
11
  # Logging is available everywhere through the {#logger} object.
12
12
  #
@@ -26,7 +26,7 @@ module OpenHAB
26
26
  # @example The following entries are in a file named 'log_test.rb'
27
27
  # rule 'foo' do
28
28
  # run { logger.trace('Test logging at trace') } # 2020-12-03 18:05:20.903 [TRACE] [org.openhab.automation.jrubyscripting.foo] - Test logging at trace
29
- # on_start
29
+ # on_load
30
30
  # end
31
31
  #
32
32
  #
@@ -122,7 +122,7 @@ module OpenHAB
122
122
  end
123
123
 
124
124
  #
125
- # Ruby Logger that forwards messages at appropriate levels to OpenHAB Logger
125
+ # Ruby Logger that forwards messages at appropriate levels to openHAB Logger
126
126
  #
127
127
  class Logger
128
128
  # The base prefix for all loggers from this gem.
@@ -150,7 +150,7 @@ module OpenHAB
150
150
  private_constant :JAVA_INTERNAL_CALL_REGEX
151
151
 
152
152
  class << self
153
- # The root logger (all of OpenHAB)
153
+ # The root logger (all of openHAB)
154
154
  # @return [Logger]
155
155
  def root
156
156
  Log.logger(org.slf4j.Logger::ROOT_LOGGER_NAME)
@@ -299,7 +299,7 @@ module OpenHAB
299
299
  end
300
300
 
301
301
  #
302
- # Log a message to the OpenHAB Logger
302
+ # Log a message to the openHAB Logger
303
303
  #
304
304
  # @param [Symbol] severity Severity to log message at
305
305
  # @param [Object] msg to log, if no msg supplied and a block is provided,
@@ -3,13 +3,13 @@
3
3
  module OpenHAB
4
4
  module RSpec
5
5
  #
6
- # Contains configuration for how the OpenHAB instance should be set
6
+ # Contains configuration for how the openHAB instance should be set
7
7
  # up for the testing environment.
8
8
  #
9
9
  module Configuration
10
10
  class << self
11
11
  #
12
- # Copy binding configuration from the root OpenHAB instance.
12
+ # Copy binding configuration from the root openHAB instance.
13
13
  #
14
14
  # Default `true`.
15
15
  # @return [true, false]
@@ -18,7 +18,7 @@ module OpenHAB
18
18
 
19
19
  #
20
20
  # Copy the JSONDB (managed thing and item configuration) from the root
21
- # OpenHAB instance.
21
+ # openHAB instance.
22
22
  #
23
23
  # Default `true`.
24
24
  #
@@ -28,7 +28,7 @@ module OpenHAB
28
28
 
29
29
  #
30
30
  # Use a private (empty) confdir (scripts, rules, items, and things
31
- # files), instead of sharing with the root OpenHAB instance.
31
+ # files), instead of sharing with the root openHAB instance.
32
32
  #
33
33
  # Default `false`.
34
34
  #
@@ -37,7 +37,7 @@ module OpenHAB
37
37
  attr_accessor :private_confdir
38
38
 
39
39
  #
40
- # Use the root OpenHAB instance directly, rather than creating a
40
+ # Use the root openHAB instance directly, rather than creating a
41
41
  # private (but linked) instance.
42
42
  #
43
43
  # Default `false`.
@@ -94,7 +94,7 @@ module OpenHAB
94
94
  # it "logs exceptions in rule execution" do
95
95
  # expect(self.class.propagate_exceptions?).to be false
96
96
  # rule do
97
- # on_start
97
+ # on_load
98
98
  # run { raise "exception is logged" }
99
99
  # end
100
100
  # expect(spec_log_lines).to include(match(/exception is logged/))
@@ -52,7 +52,7 @@ module OpenHAB
52
52
  module RSpec
53
53
  #
54
54
  # Provides helper methods for use in specs, to easily work with and adjust
55
- # the OpenHAB environment.
55
+ # the openHAB environment.
56
56
  #
57
57
  # These methods are automatically available in RSpec spec blocks, as well
58
58
  # as other per-spec hooks like `before` and `after`. You can also call them
@@ -124,7 +124,7 @@ module OpenHAB
124
124
  #
125
125
  def time_travel_and_execute_timers(duration)
126
126
  if self.class.mock_timers?
127
- Timecop.travel(duration)
127
+ Timecop.frozen? ? Timecop.freeze(duration) : Timecop.travel(duration)
128
128
  execute_timers
129
129
  else
130
130
  sleep duration
@@ -175,7 +175,7 @@ module OpenHAB
175
175
  end
176
176
 
177
177
  #
178
- # Require all files configured to be autorequired with the jrubyscripting addon in OpenHAB.
178
+ # Require all files configured to be autorequired with the jrubyscripting addon in openHAB.
179
179
  #
180
180
  # This method is normally called by RSpec hooks.
181
181
  #
@@ -306,7 +306,7 @@ module OpenHAB
306
306
  end
307
307
 
308
308
  #
309
- # Install an OpenHAB addon
309
+ # Install an openHAB addon
310
310
  #
311
311
  # @param [String] addon_id The addon id, such as "binding-mqtt"
312
312
  # @param [true,false] wait Wait until OSGi has confirmed the bundle is installed and running before returning.
@@ -348,7 +348,7 @@ module OpenHAB
348
348
  end
349
349
  end
350
350
 
351
- # @return [String] The filename of the OpenHAB log.
351
+ # @return [String] The filename of the openHAB log.
352
352
  def log_file
353
353
  "#{java.lang.System.get_property("openhab.logdir", nil)}/openhab.log"
354
354
  end
@@ -3,7 +3,7 @@
3
3
  module OpenHAB
4
4
  #
5
5
  # This module contains helper methods, hooks, and infrastracture to
6
- # boot OpenHAB inside of JRuby, and run RSpec (or other Ruby processes)
6
+ # boot openHAB inside of JRuby, and run RSpec (or other Ruby processes)
7
7
  # in that context.
8
8
  #
9
9
  # @see file:testing.md Testing Your Rules
@@ -11,6 +11,14 @@ module OpenHAB
11
11
  module RSpec
12
12
  Object.include Helpers if defined?(IRB)
13
13
 
14
+ # @!visibility private
15
+ module Hooks
16
+ class << self
17
+ attr_accessor :cache_script_extension
18
+ end
19
+ self.cache_script_extension = nil
20
+ end
21
+
14
22
  Helpers.launch_karaf(
15
23
  include_bindings: Configuration.include_bindings,
16
24
  include_jsondb: Configuration.include_jsondb,
@@ -28,6 +36,15 @@ module OpenHAB
28
36
  Helpers.send(:set_up_autoupdates)
29
37
  Helpers.load_transforms
30
38
  Helpers.load_rules
39
+
40
+ if DSL.shared_cache
41
+ Hooks.cache_script_extension = OSGi.service(
42
+ "org.openhab.core.automation.module.script.ScriptExtensionProvider",
43
+ filter:
44
+ "(component.name=org.openhab.core.automation.module.script.rulesupport.internal.CacheScriptExtension)"
45
+ )
46
+ Hooks.cache_script_extension.class.field_reader :sharedCache
47
+ end
31
48
  end
32
49
 
33
50
  config.before do
@@ -79,6 +96,7 @@ module OpenHAB
79
96
  Timecop.return
80
97
  restore_autoupdate_items
81
98
  Mocks::PersistenceService.instance.reset
99
+ Hooks.cache_script_extension.sharedCache.clear if DSL.shared_cache
82
100
  end
83
101
  end
84
102
  end
@@ -20,6 +20,14 @@ module OpenHAB
20
20
  def get(type)
21
21
  @manager.get(type, "jruby")
22
22
  end
23
+
24
+ def default_presets
25
+ @manager.default_presets
26
+ end
27
+
28
+ def import_preset(preset)
29
+ @manager.find_preset(preset, "rspec")
30
+ end
23
31
  end
24
32
  private_constant :ScriptExtensionManagerWrapper
25
33
 
@@ -73,7 +81,7 @@ module OpenHAB
73
81
  service = org.apache.karaf.instance.core.internal.InstanceServiceImpl.new
74
82
  settings = org.apache.karaf.instance.core.InstanceSettings.new(0, 0, 0, path, nil, nil, nil)
75
83
  root_instance = service.instances.find(&:root?)
76
- raise ArgumentError "No root instance found to clone... has OpenHAB run yet?" unless root_instance
84
+ raise ArgumentError "No root instance found to clone... has openHAB run yet?" unless root_instance
77
85
 
78
86
  return if service.get_instance("rspec")
79
87
 
@@ -121,7 +129,7 @@ module OpenHAB
121
129
  launch_karaf
122
130
  at_exit do
123
131
  @main.destroy
124
- # OSGi/OpenHAB leave a ton of threads around. Kill ourselves ASAP
132
+ # OSGi/openHAB leave a ton of threads around. Kill ourselves ASAP
125
133
  code = if $!.nil? || ($!.is_a?(SystemExit) && $!.success?)
126
134
  0
127
135
  elsif $!.is_a?(SystemExit)
@@ -351,8 +359,7 @@ module OpenHAB
351
359
  }.freeze
352
360
  private_constant :BLOCKED_COMPONENTS
353
361
 
354
- START_LEVEL_OVERRIDES = {
355
- }.freeze
362
+ START_LEVEL_OVERRIDES = {}.freeze
356
363
  private_constant :START_LEVEL_OVERRIDES
357
364
 
358
365
  def set_up_bundle_listener
@@ -567,21 +574,6 @@ module OpenHAB
567
574
  wait_for_service("org.openhab.core.automation.module.script.internal.ScriptExtensionManager") do |sem|
568
575
  # since we're not created by the ScriptEngineManager, this never gets set; manually set it
569
576
  $se = $scriptExtension = ScriptExtensionManagerWrapper.new(sem)
570
- scope_values = sem.find_default_presets("rspec")
571
- scope_values = scope_values.entry_set.to_a
572
-
573
- scope_values.each do |entry|
574
- key = entry.key
575
- value = entry.value
576
- # convert Java classes to Ruby classes
577
- value = value.ruby_class if value.is_a?(java.lang.Class) # rubocop:disable Lint/UselessAssignment
578
- # variables are globals; constants go into the global namespace
579
- key = case key[0]
580
- when "a".."z" then "$#{key}"
581
- when "A".."Z" then "::#{key}"
582
- end
583
- eval("#{key} = value unless defined?(#{key})", nil, __FILE__, __LINE__) # rubocop:disable Security/Eval
584
- end
585
577
  end
586
578
  end
587
579
 
@@ -732,7 +724,7 @@ module OpenHAB
732
724
  sls = OSGi.service("org.openhab.core.service.StartLevelService")
733
725
 
734
726
  unless sls
735
- # try a different (hacky!) way to get it, since in OpenHAB 3.2.0 it's not exposed as a service
727
+ # try a different (hacky!) way to get it, since in openHAB 3.2.0 it's not exposed as a service
736
728
  scr = OSGi.service("org.osgi.service.component.runtime.ServiceComponentRuntime")
737
729
  scr.class.field_reader :componentRegistry
738
730
  cr = scr.componentRegistry
@@ -772,7 +764,7 @@ module OpenHAB
772
764
  File.write("#{oh_userdata}/etc/org.apache.karaf.features.xml", <<~XML)
773
765
  <?xml version="1.0" encoding="UTF-8"?>
774
766
  <featuresProcessing xmlns="http://karaf.apache.org/xmlns/features-processing/v1.0.0" xmlns:f="http://karaf.apache.org/xmlns/features/v1.6.0">
775
- <!-- From OpenHAB 3.2.0 -->
767
+ <!-- From openHAB 3.2.0 -->
776
768
  <bundleReplacements>
777
769
  <bundle originalUri="mvn:org.ops4j.pax.logging/pax-logging-api/[0,2.0.13)" replacement="mvn:org.ops4j.pax.logging/pax-logging-api/2.0.13" mode="maven" />
778
770
  <bundle originalUri="mvn:org.ops4j.pax.logging/pax-logging-log4j2/[0,2.0.13)" replacement="mvn:org.ops4j.pax.logging/pax-logging-log4j2/2.0.13" mode="maven" />
@@ -19,6 +19,21 @@ module OpenHAB
19
19
  end
20
20
  end
21
21
 
22
+ module HistoricState
23
+ def timestamp
24
+ # PersistenceExtensions uses an anonymous class to wrap the current
25
+ # state if that happens to be an answer. Except it calls
26
+ # ZonedDateTime.now in Java land, bypassing Timecop.
27
+ # Detect that and make the call in Ruby
28
+ #
29
+ jc = @historic_item.class.java_class
30
+ return ZonedDateTime.now if jc.anonymous? && jc.enclosing_class == PersistenceExtensions.java_class
31
+
32
+ super
33
+ end
34
+ end
35
+ Core::Items::Persistence::HistoricState.prepend(HistoricState)
36
+
22
37
  attr_reader :id
23
38
 
24
39
  def initialize
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Naming have to follow java interface names
3
+ # rubocop:disable Naming/MethodName, Naming/AccessorMethodName
4
4
 
5
5
  require "singleton"
6
6
 
@@ -73,4 +73,4 @@ module OpenHAB
73
73
  end
74
74
  end
75
75
  end
76
- # rubocop:enable Naming
76
+ # rubocop:enable Naming/MethodName, Naming/AccessorMethodName
@@ -18,7 +18,8 @@ module OpenHAB
18
18
  logger.trace { "Execute called with mod (#{mod&.to_string}) and inputs (#{inputs.inspect})" }
19
19
  logger.trace { "Event details #{inputs["event"].inspect}" } if inputs&.key?("event")
20
20
  trigger_conditions(inputs).process(mod: mod, inputs: inputs) do
21
- process_queue(create_queue(inputs), mod, inputs)
21
+ event = extract_event(inputs)
22
+ process_queue(create_queue(event), mod, event)
22
23
  end
23
24
  rescue Exception => e
24
25
  raise if defined?(::RSpec) && ::RSpec.current_example.example_group.propagate_exceptions?
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "nokogiri"
4
+
5
+ module OpenHAB
6
+ module YARD
7
+ # @!visibility private
8
+ module BaseHelper
9
+ def preprocess(text)
10
+ html = Nokogiri::HTML5.fragment(text)
11
+
12
+ context = if ENV["ADDON"]
13
+ :addon
14
+ else
15
+ :yard
16
+ end
17
+
18
+ # process directives on which content is supposed to be included in this context
19
+ node = html.children.first
20
+ loop do
21
+ break unless node
22
+
23
+ next_node = node.next
24
+
25
+ if node.comment? && (directive = MarkdownDirective.new(node)).directive?
26
+ next_node = directive.process(context) || next_node
27
+ end
28
+ node = next_node
29
+ end
30
+
31
+ html.to_s
32
+ end
33
+
34
+ def link_object(obj, title = nil, *)
35
+ ::YARD::Handlers::JRuby::Base.infer_java_class(obj) if obj.is_a?(String)
36
+ obj = ::YARD::Registry.resolve(object, obj, true, true) if obj.is_a?(String)
37
+ if obj.is_a?(::YARD::CodeObjects::Java::Base) && (see = obj.docstring.tag(:see))
38
+ # link to the first see tag
39
+ return linkify(see.name, title&.to_s || see.text)
40
+ end
41
+
42
+ super
43
+ end
44
+ end
45
+ end
46
+ end
@@ -16,8 +16,8 @@ module OpenHAB
16
16
 
17
17
  # have to completely replace this method. only change is the regex splitting
18
18
  # into parts now allows `.` as part of the identifier
19
- # rubocop:disable Style
20
- def format_types(typelist, brackets = true)
19
+ # rubocop:disable Style/NestedTernaryOperator, Style/StringConcatenation, Style/TernaryParentheses
20
+ def format_types(typelist, brackets = true) # rubocop:disable Style/OptionalBooleanParameter
21
21
  return unless typelist.is_a?(Array)
22
22
 
23
23
  list = typelist.map do |type|
@@ -27,7 +27,7 @@ module OpenHAB
27
27
  end
28
28
  list.empty? ? "" : (brackets ? "(#{list.join(", ")})" : list.join(", "))
29
29
  end
30
- # rubocop:enable Style
30
+ # rubocop:enable Style/NestedTernaryOperator, Style/StringConcatenation, Style/TernaryParentheses
31
31
 
32
32
  def link_object(obj, title = nil, *)
33
33
  ::YARD::Handlers::JRuby::Base.infer_java_class(obj) if obj.is_a?(String)
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "nokogiri"
4
+
5
+ module OpenHAB
6
+ module YARD
7
+ # @!visibility private
8
+ class MarkdownDirective
9
+ attr_reader :comment, :context
10
+
11
+ def initialize(comment)
12
+ @comment = comment
13
+ @lines = comment.text.split("\n")
14
+ directive_text = @lines.first.strip
15
+
16
+ @multiline = @lines.length > 1
17
+ @directive = false
18
+ return unless (match = directive_text.match(%r{^<(/)?(!)?([a-z]+)-only>$}))
19
+
20
+ @closing = match[1]
21
+ @context = match[3].to_sym
22
+ @inverted = match[2]
23
+
24
+ if closing? && multiline?
25
+ log.warn "In file `#{file}':#{line}: Multiline closing directives are not allowed (#{directive_text})."
26
+ return
27
+ end
28
+ @directive = true
29
+ end
30
+
31
+ def directive?
32
+ @directive
33
+ end
34
+
35
+ def multiline?
36
+ @multiline
37
+ end
38
+
39
+ def closing?
40
+ @closing
41
+ end
42
+
43
+ def inverted?
44
+ @inverted
45
+ end
46
+
47
+ def match?(context)
48
+ result = context == self.context
49
+ result = !result if inverted?
50
+ result
51
+ end
52
+
53
+ def closing_directive
54
+ return nil if multiline?
55
+
56
+ unless instance_variable_defined?(:@closing_directive)
57
+ next_node = @comment.next
58
+ loop do
59
+ return @closing_directive = nil unless next_node
60
+
61
+ if next_node.comment?
62
+ directive = MarkdownDirective.new(next_node)
63
+ if directive.directive? &&
64
+ directive.closing? &&
65
+ directive.context == context &&
66
+ directive.inverted? == inverted?
67
+ return @closing_directive = next_node
68
+ end
69
+ end
70
+
71
+ next_node = next_node.next
72
+ end
73
+ end
74
+ @closing_directive
75
+ end
76
+
77
+ def process(context)
78
+ return unless directive?
79
+ return if closing?
80
+
81
+ matched = match?(context)
82
+
83
+ # if it's a matched multiline, extract the contents and insert them directly,
84
+ # and remove the comment
85
+ if multiline?
86
+ result = comment.next
87
+ comment.before(Nokogiri::HTML5.fragment(@lines[1..].join("\n"))) if matched
88
+ comment.remove
89
+ return result
90
+ end
91
+
92
+ unless closing_directive
93
+ log.warn "In file `#{file}':#{line}: Unmatched directive <#{"!" if inverted?}#{context}-only>."
94
+ return
95
+ end
96
+
97
+ result = closing_directive.next
98
+
99
+ unless matched
100
+ # remove all nodes between the opening and closing directives
101
+ comment.next.remove while comment.next != closing_directive
102
+ end
103
+ # now remove the directives themselves
104
+ closing_directive.remove
105
+ comment.remove
106
+ result
107
+ end
108
+
109
+ def file
110
+ ((defined?(@file) && @file) ? @file.filename : object.file) || "(unknown)"
111
+ end
112
+
113
+ def line
114
+ return @line if instance_variable_defined?(@line)
115
+
116
+ @line = (if defined?(@file) && @file
117
+ 1
118
+ else
119
+ (object.docstring.line_range ? object.docstring.line_range.first : 1)
120
+ end) + (match ? $`.count("\n") : 0)
121
+ @line += comment.line - 1
122
+ end
123
+ end
124
+ end
125
+ end