openhab-jrubyscripting 5.0.0.rc1 → 5.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/lib/openhab/core/entity_lookup.rb +1 -12
  3. data/lib/openhab/core/items/generic_item.rb +15 -7
  4. data/lib/openhab/core/items/metadata/hash.rb +81 -39
  5. data/lib/openhab/core/items/metadata/namespace_hash.rb +17 -19
  6. data/lib/openhab/core/items/metadata/provider.rb +48 -0
  7. data/lib/openhab/core/items/persistence.rb +2 -0
  8. data/lib/openhab/core/items/provider.rb +40 -0
  9. data/lib/openhab/core/items/proxy.rb +10 -0
  10. data/lib/openhab/core/items/registry.rb +16 -7
  11. data/lib/openhab/core/items/semantics/enumerable.rb +6 -4
  12. data/lib/openhab/core/items/state_storage.rb +3 -3
  13. data/lib/openhab/core/profile_factory.rb +3 -1
  14. data/lib/openhab/core/provider.rb +223 -0
  15. data/lib/openhab/core/registry.rb +30 -0
  16. data/lib/openhab/core/rules/provider.rb +25 -0
  17. data/lib/openhab/core/rules/registry.rb +76 -0
  18. data/lib/openhab/core/rules/rule.rb +150 -0
  19. data/lib/openhab/core/rules.rb +25 -0
  20. data/lib/openhab/core/script_handling.rb +50 -0
  21. data/lib/openhab/core/things/links/provider.rb +40 -0
  22. data/lib/openhab/core/things/provider.rb +25 -0
  23. data/lib/openhab/core/things/proxy.rb +10 -0
  24. data/lib/openhab/core/things/registry.rb +25 -2
  25. data/lib/openhab/core/timer.rb +17 -7
  26. data/lib/openhab/core/types/quantity_type.rb +5 -2
  27. data/lib/openhab/core/types.rb +1 -1
  28. data/lib/openhab/core.rb +3 -30
  29. data/lib/openhab/core_ext/java/class.rb +34 -0
  30. data/lib/openhab/core_ext/java/list.rb +436 -0
  31. data/lib/openhab/core_ext/java/local_time.rb +2 -1
  32. data/lib/openhab/core_ext/java/map.rb +66 -0
  33. data/lib/openhab/core_ext/java/month.rb +2 -1
  34. data/lib/openhab/core_ext/java/zoned_date_time.rb +1 -2
  35. data/lib/openhab/core_ext/ruby/date.rb +2 -0
  36. data/lib/openhab/core_ext/ruby/date_time.rb +53 -0
  37. data/lib/openhab/core_ext/ruby/time.rb +88 -86
  38. data/lib/openhab/dsl/events/watch_event.rb +1 -1
  39. data/lib/openhab/dsl/items/builder.rb +38 -100
  40. data/lib/openhab/dsl/items/ensure.rb +6 -2
  41. data/lib/openhab/dsl/items/timed_command.rb +10 -11
  42. data/lib/openhab/dsl/rules/automation_rule.rb +36 -13
  43. data/lib/openhab/dsl/rules/builder.rb +126 -8
  44. data/lib/openhab/dsl/rules/name_inference.rb +0 -5
  45. data/lib/openhab/dsl/rules/terse.rb +1 -2
  46. data/lib/openhab/dsl/rules/triggers/changed.rb +7 -4
  47. data/lib/openhab/dsl/rules/triggers/conditions/duration.rb +17 -53
  48. data/lib/openhab/dsl/rules/triggers/conditions/proc.rb +0 -3
  49. data/lib/openhab/dsl/rules/triggers/cron/cron.rb +1 -1
  50. data/lib/openhab/dsl/rules/triggers/trigger.rb +1 -1
  51. data/lib/openhab/dsl/rules/triggers/updated.rb +7 -3
  52. data/lib/openhab/dsl/rules/triggers/watch/watch_handler.rb +1 -1
  53. data/lib/openhab/dsl/rules.rb +0 -21
  54. data/lib/openhab/dsl/script_handling.rb +0 -49
  55. data/lib/openhab/dsl/things/builder.rb +8 -31
  56. data/lib/openhab/dsl/thread_local.rb +3 -2
  57. data/lib/openhab/dsl/timer_manager.rb +16 -8
  58. data/lib/openhab/dsl/version.rb +1 -1
  59. data/lib/openhab/dsl.rb +137 -120
  60. data/lib/openhab/log.rb +3 -3
  61. data/lib/openhab/rspec/example_group.rb +42 -0
  62. data/lib/openhab/rspec/helpers.rb +33 -27
  63. data/lib/openhab/rspec/hooks.rb +17 -23
  64. data/lib/openhab/rspec/karaf.rb +45 -27
  65. data/lib/openhab/rspec/mocks/synchronous_executor.rb +11 -4
  66. data/lib/openhab/rspec/mocks/timer.rb +7 -1
  67. data/lib/openhab/rspec/suspend_rules.rb +4 -2
  68. metadata +30 -3
  69. data/lib/openhab/rspec/mocks/metadata_provider.rb +0 -75
@@ -77,7 +77,12 @@ module OpenHAB
77
77
 
78
78
  return if service.get_instance("rspec")
79
79
 
80
- service.clone_instance(root_instance.name, "rspec", settings, false)
80
+ begin
81
+ service.clone_instance(root_instance.name, "rspec", settings, false)
82
+ rescue java.lang.NullPointerException
83
+ retry if fix_rmi_registry_npe
84
+ raise
85
+ end
81
86
  ensure
82
87
  extra_loaders = ::JRuby.runtime.instance_config.extra_loaders
83
88
  loader = extra_loaders.find { |l| l.class_loader == @karaf_instance_loader }
@@ -99,6 +104,7 @@ module OpenHAB
99
104
  java.lang.System.set_property("felix.cm.dir", felix_cm)
100
105
  # not handled by karaf instances
101
106
  java.lang.System.set_property("openhab.userdata", path)
107
+ @oh_userdata = nil
102
108
  java.lang.System.set_property("openhab.logdir", "#{path}/logs")
103
109
  end
104
110
  cleanup_instance
@@ -129,6 +135,7 @@ module OpenHAB
129
135
 
130
136
  set_up_bundle_listener
131
137
  wait_for_start
138
+ Mocks::SynchronousExecutor.instance.main_thread = Thread.current
132
139
  set_jruby_script_presets
133
140
  @main
134
141
  end
@@ -258,8 +265,6 @@ module OpenHAB
258
265
  props.remove("transformation")
259
266
  props.remove("ui")
260
267
  props.remove("binding") unless include_bindings
261
- # except we need jrubyscripting
262
- props.put("automation", "jrubyscripting")
263
268
  cfg.update(props)
264
269
 
265
270
  # configure persistence to use the mock service
@@ -302,7 +307,6 @@ module OpenHAB
302
307
  private_constant :BLOCKED_BUNDLE_TREES
303
308
 
304
309
  ALLOWED_BUNDLES = %w[
305
- org.openhab.automation.jrubyscripting
306
310
  org.openhab.core.io.monitor
307
311
  ].freeze
308
312
  private_constant :ALLOWED_BUNDLES
@@ -420,12 +424,18 @@ module OpenHAB
420
424
  java.util.Hashtable.new(org.osgi.framework.Constants::SERVICE_RANKING => 1.to_java(:int))
421
425
  )
422
426
 
423
- require_relative "mocks/thing_handler"
424
- thf = Mocks::ThingHandlerFactory.instance
425
- bundle = org.osgi.framework.FrameworkUtil.get_bundle(org.openhab.core.thing.Thing)
426
- Mocks::BundleResolver.instance.register_class(thf.class, bundle)
427
- bundle.bundle_context.register_service(org.openhab.core.thing.binding.ThingHandlerFactory.java_class, thf,
428
- nil)
427
+ wait_for_service("org.openhab.core.thing.ThingManager") do |tm|
428
+ tm.class.field_accessor :bundleResolver
429
+
430
+ tm.bundleResolver = Mocks::BundleResolver.instance
431
+
432
+ require_relative "mocks/thing_handler"
433
+ thf = Mocks::ThingHandlerFactory.instance
434
+ bundle = org.osgi.framework.FrameworkUtil.get_bundle(org.openhab.core.thing.Thing)
435
+ Mocks::BundleResolver.instance.register_class(thf.class, bundle)
436
+ bundle.bundle_context.register_service(org.openhab.core.thing.binding.ThingHandlerFactory.java_class, thf,
437
+ nil)
438
+ end
429
439
  end
430
440
  if bundle_name == "org.openhab.core.automation"
431
441
  org.openhab.core.automation.internal.TriggerHandlerCallbackImpl.field_accessor :executor
@@ -549,31 +559,22 @@ module OpenHAB
549
559
  # import global variables and constants that the DSL expects,
550
560
  # since we're going to be running it in this same VM
551
561
  def set_jruby_script_presets
552
- wait_for_service("org.openhab.core.automation.module.script.ScriptEngineFactory",
553
- filter: "(service.config.description.uri=automation:jruby)") do |jrubyscripting|
554
- # "org.openhab.core.automation.module.script.internal.ScriptExtensionManager") do |sem|
555
- sem = OSGi.service(
556
- "org.openhab.core.automation.module.script.internal.ScriptExtensionManager"
557
- )
562
+ wait_for_service("org.openhab.core.automation.module.script.internal.ScriptExtensionManager") do |sem|
558
563
  # since we're not created by the ScriptEngineManager, this never gets set; manually set it
559
564
  $se = $scriptExtension = ScriptExtensionManagerWrapper.new(sem)
560
565
  scope_values = sem.find_default_presets("rspec")
561
- scope_values = scope_values.entry_set
562
-
563
- %w[mapInstancePresets mapGlobalPresets].each do |method_name|
564
- method = jrubyscripting.class.java_class.get_declared_method(method_name, java.util.Map::Entry.java_class)
565
-
566
- method.accessible = true
567
- scope_values = scope_values.map { |e| method.invoke(nil, e) }
568
- end
566
+ scope_values = scope_values.entry_set.to_a
569
567
 
570
568
  scope_values.each do |entry|
571
569
  key = entry.key
572
570
  value = entry.value
573
571
  # convert Java classes to Ruby classes
574
572
  value = value.ruby_class if value.is_a?(java.lang.Class) # rubocop:disable Lint/UselessAssignment
575
- # constants need to go into the global namespace
576
- key = "::#{key}" if ("A".."Z").cover?(key[0])
573
+ # variables are globals; constants go into the global namespace
574
+ key = case key[0]
575
+ when "a".."z" then "$#{key}"
576
+ when "A".."Z" then "::#{key}"
577
+ end
577
578
  eval("#{key} = value unless defined?(#{key})", nil, __FILE__, __LINE__) # rubocop:disable Security/Eval
578
579
  end
579
580
  end
@@ -796,7 +797,6 @@ module OpenHAB
796
797
  <f:feature>openhab-core-model-sitemap</f:feature>
797
798
  <f:feature>openhab-core-model-thing</f:feature>
798
799
  <f:feature>openhab-core-storage-json</f:feature>
799
- <f:feature>openhab-automation-jrubyscripting</f:feature>
800
800
  <f:feature>openhab-transport-http</f:feature>
801
801
  <f:feature prerequisite="true">wrapper</f:feature>
802
802
  <f:bundle>mvn:org.openhab.core.bundles/org.openhab.core.karaf/#{version}</f:bundle>
@@ -806,6 +806,24 @@ module OpenHAB
806
806
  </featuresProcessing>
807
807
  XML
808
808
  end
809
+
810
+ def fix_rmi_registry_npe
811
+ full_path = File.join(oh_userdata, "etc/org.apache.karaf.management.cfg")
812
+ stat = File.stat(full_path)
813
+ return false unless stat.file? && stat.size.zero?
814
+
815
+ contents = <<~TEXT
816
+ # This file was autogenerated by openhab-jrubyscripting.
817
+ # Feel free to customize.
818
+ rmiRegistryPort = 1099
819
+ rmiServerPort = 44444
820
+ TEXT
821
+ begin
822
+ File.write(full_path, contents)
823
+ rescue Errno::EACCESS
824
+ abort "Unable to write to `#{full_path}`. Please use sudo and set it to:\n\n#{contents}"
825
+ end
826
+ end
809
827
  end
810
828
  end
811
829
  end
@@ -16,19 +16,25 @@ module OpenHAB
16
16
  end
17
17
 
18
18
  class SynchronousExecutor < java.util.concurrent.ScheduledThreadPoolExecutor
19
- class << self
20
- def instance
21
- @instance ||= new(1)
22
- end
19
+ include Singleton
20
+
21
+ attr_accessor :main_thread
22
+
23
+ def initialize
24
+ super(1)
23
25
  end
24
26
 
25
27
  def submit(runnable)
28
+ return super unless Thread.current == main_thread
29
+
26
30
  runnable.respond_to?(:run) ? runnable.run : runnable.call
27
31
 
28
32
  java.util.concurrent.CompletableFuture.completed_future(nil)
29
33
  end
30
34
 
31
35
  def execute(runnable)
36
+ return super unless Thread.current == main_thread
37
+
32
38
  runnable.run
33
39
  end
34
40
 
@@ -37,6 +43,7 @@ module OpenHAB
37
43
  def shutdown_now
38
44
  []
39
45
  end
46
+ alias_method :shutdownNow, :shutdown_now
40
47
  end
41
48
 
42
49
  class SynchronousExecutorMap
@@ -50,6 +50,7 @@ module OpenHAB
50
50
  end
51
51
 
52
52
  def reschedule(time = nil)
53
+ Thread.current[:openhab_rescheduled_timer] = true if Thread.current[:openhab_rescheduled_timer] == self
53
54
  @execution_time = new_execution_time(time || @time)
54
55
  @executed = false
55
56
 
@@ -62,14 +63,19 @@ module OpenHAB
62
63
  raise "Timer already cancelled" if cancelled?
63
64
  raise "Timer already executed" if terminated?
64
65
 
65
- super
66
66
  @executed = true
67
+ super
67
68
  end
68
69
 
69
70
  def cancel
70
71
  return false if terminated? || cancelled?
71
72
 
72
73
  DSL::TimerManager.instance.delete(self)
74
+ cancel!
75
+ true
76
+ end
77
+
78
+ def cancel!
73
79
  @execution_time = nil
74
80
  true
75
81
  end
@@ -21,7 +21,9 @@ module OpenHAB
21
21
  process_queue(create_queue(inputs), mod, inputs)
22
22
  end
23
23
  rescue Exception => e
24
- @run_context.logger.log_exception(e)
24
+ raise if defined?(::RSpec) && ::RSpec.current_example.example_group.propagate_exceptions?
25
+
26
+ @run_context.send(:logger).log_exception(e)
25
27
  end
26
28
  end
27
29
  end
@@ -29,7 +31,7 @@ module OpenHAB
29
31
  # DSL::Rules::AutomationRule.prepend(AutomationRule)
30
32
 
31
33
  module DSL
32
- def after(*)
34
+ def after(*, **)
33
35
  return if SuspendRules.suspended?
34
36
 
35
37
  super
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openhab-jrubyscripting
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0.rc1
4
+ version: 5.0.0.rc3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cody Cutrer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-17 00:00:00.000000000 Z
11
+ date: 2022-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: ruby2_keywords
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: cucumber
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -336,10 +350,12 @@ files:
336
350
  - lib/openhab/core/items/metadata.rb
337
351
  - lib/openhab/core/items/metadata/hash.rb
338
352
  - lib/openhab/core/items/metadata/namespace_hash.rb
353
+ - lib/openhab/core/items/metadata/provider.rb
339
354
  - lib/openhab/core/items/number_item.rb
340
355
  - lib/openhab/core/items/numeric_item.rb
341
356
  - lib/openhab/core/items/persistence.rb
342
357
  - lib/openhab/core/items/player_item.rb
358
+ - lib/openhab/core/items/provider.rb
343
359
  - lib/openhab/core/items/proxy.rb
344
360
  - lib/openhab/core/items/registry.rb
345
361
  - lib/openhab/core/items/rollershutter_item.rb
@@ -350,12 +366,20 @@ files:
350
366
  - lib/openhab/core/items/switch_item.rb
351
367
  - lib/openhab/core/lazy_array.rb
352
368
  - lib/openhab/core/profile_factory.rb
369
+ - lib/openhab/core/provider.rb
370
+ - lib/openhab/core/registry.rb
371
+ - lib/openhab/core/rules.rb
372
+ - lib/openhab/core/rules/provider.rb
373
+ - lib/openhab/core/rules/registry.rb
374
+ - lib/openhab/core/rules/rule.rb
353
375
  - lib/openhab/core/script_handling.rb
354
376
  - lib/openhab/core/things.rb
355
377
  - lib/openhab/core/things/channel.rb
356
378
  - lib/openhab/core/things/channel_uid.rb
357
379
  - lib/openhab/core/things/item_channel_link.rb
380
+ - lib/openhab/core/things/links/provider.rb
358
381
  - lib/openhab/core/things/profile_callback.rb
382
+ - lib/openhab/core/things/provider.rb
359
383
  - lib/openhab/core/things/proxy.rb
360
384
  - lib/openhab/core/things/registry.rb
361
385
  - lib/openhab/core/things/thing.rb
@@ -384,9 +408,12 @@ files:
384
408
  - lib/openhab/core/types/up_down_type.rb
385
409
  - lib/openhab/core/uid.rb
386
410
  - lib/openhab/core_ext.rb
411
+ - lib/openhab/core_ext/java/class.rb
387
412
  - lib/openhab/core_ext/java/duration.rb
413
+ - lib/openhab/core_ext/java/list.rb
388
414
  - lib/openhab/core_ext/java/local_date.rb
389
415
  - lib/openhab/core_ext/java/local_time.rb
416
+ - lib/openhab/core_ext/java/map.rb
390
417
  - lib/openhab/core_ext/java/month.rb
391
418
  - lib/openhab/core_ext/java/month_day.rb
392
419
  - lib/openhab/core_ext/java/period.rb
@@ -397,6 +424,7 @@ files:
397
424
  - lib/openhab/core_ext/ruby/array.rb
398
425
  - lib/openhab/core_ext/ruby/class.rb
399
426
  - lib/openhab/core_ext/ruby/date.rb
427
+ - lib/openhab/core_ext/ruby/date_time.rb
400
428
  - lib/openhab/core_ext/ruby/numeric.rb
401
429
  - lib/openhab/core_ext/ruby/range.rb
402
430
  - lib/openhab/core_ext/ruby/time.rb
@@ -444,7 +472,6 @@ files:
444
472
  - lib/openhab/rspec/mocks/bundle_install_support.rb
445
473
  - lib/openhab/rspec/mocks/bundle_resolver.rb
446
474
  - lib/openhab/rspec/mocks/event_admin.rb
447
- - lib/openhab/rspec/mocks/metadata_provider.rb
448
475
  - lib/openhab/rspec/mocks/persistence_service.rb
449
476
  - lib/openhab/rspec/mocks/safe_caller.rb
450
477
  - lib/openhab/rspec/mocks/synchronous_executor.rb
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module OpenHAB
4
- module RSpec
5
- module Mocks
6
- class MetadataProvider
7
- org.openhab.core.common.registry.Identifiable
8
- include org.openhab.core.items.ManagedMetadataProvider
9
-
10
- def initialize(parent)
11
- @metadata = {}
12
- @listeners = []
13
- @parent = parent
14
- @removed_from_parent = []
15
- end
16
-
17
- def addProviderChangeListener(listener) # rubocop:disable Naming/MethodName required by java interface
18
- @listeners << listener
19
- end
20
-
21
- def removeProviderChangeListener(listener) # rubocop:disable Naming/MethodName required by java interface
22
- old = @listeners.delete(listener)
23
- return unless old
24
-
25
- @listeners.each { |l| l.removed(self, old) }
26
- end
27
-
28
- def add(metadata)
29
- @metadata[metadata.uid] = metadata
30
- @listeners.each { |l| l.added(self, metadata) }
31
- end
32
-
33
- def update(metadata)
34
- old_element = @metadata[metadata.uid]
35
- raise ArgumentError if old_element.nil?
36
-
37
- @metadata[metadata.uid] = metadata
38
- @listeners.each { |l| l.updated(self, old_element, metadata) }
39
- metadata
40
- end
41
-
42
- def remove(key)
43
- m = @parent.remove(key)
44
- @removed_from_parent << m if m
45
- m = @metadata.delete(key)
46
- @listeners.each { |l| l.removed(self, m) } if m
47
- m
48
- end
49
-
50
- def restore_parent
51
- @removed_from_parent.each do |m|
52
- @parent.add(m)
53
- end
54
- end
55
-
56
- def get(key)
57
- @metadata[key]
58
- end
59
-
60
- def getAll # rubocop:disable Naming/MethodName required by java interface
61
- @metadata.values
62
- end
63
-
64
- def removeItemMetadata(item_name) # rubocop:disable Naming/MethodName required by java interface
65
- @metadata.delete_if do |k, v|
66
- next unless k.item_name == item_name
67
-
68
- @listeners.each { |l| l.removed(self, v) }
69
- true
70
- end
71
- end
72
- end
73
- end
74
- end
75
- end