Class: OpenHAB::DSL::Rules::Triggers::WatchHandler::Watcher

Inherits:
Object
  • Object
show all
Includes:
orgorg.openhaborg.openhab.coreorg.openhab.core.serviceorg.openhab.core.service.WatchServiceorg.openhab.core.service.WatchService::WatchEventListener
Defined in:
lib/openhab/dsl/rules/triggers/watch/watch_handler.rb

Overview

A class that implements openHAB4’s WatchEventListener and also creates and removes a unique WatchService for each instance

Constant Summary collapse

STRING_TO_EVENT =

Hash of event symbols as strings to map to WatchService events

{
  created: WatchService::Kind::CREATE,
  deleted: WatchService::Kind::DELETE,
  modified: WatchService::Kind::MODIFY
}.transform_keys(&:to_s).freeze
EVENT_TO_SYMBOL =

Hash of WatchService event kinds to ruby symbols

STRING_TO_EVENT.invert.transform_values(&:to_sym).freeze

Instance Method Summary collapse

Constructor Details

#initialize(path, subdirs, types, &block) ⇒ Watcher

constructor



42
43
44
45
46
47
48
49
50
51
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 42

def initialize(path, subdirs, types, &block)
  @types = types.map { |type| STRING_TO_EVENT[type] }
  @block = block
  @subdirs = subdirs
  @path = Pathname.new(path)
  @custom_watcher = nil
  return if path.to_s.start_with?(OpenHAB::Core.config_folder.to_s)

  @custom_watcher = "jrubyscripting-#{SecureRandom.uuid}"
end

Instance Method Details

#activateObject

Creates a new Watch Service and registers ourself as a listener This isn’t an OSGi service, but it’s called by OpenHAB::DSL::Rules::Triggers::WatchHandler::WatchTriggerHandler below.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 55

def activate
  java_path = java.nio.file.Path.of(@path.to_s)

  service_name = WatchService::SERVICE_PID
  filter = if @custom_watcher
             WatchHandler.factory.create_watch_service(@custom_watcher, java_path)
             logger.trace { "Created a watch service #{@custom_watcher} for #{@path}" }
             "(name=#{@custom_watcher})"
           else
             logger.trace { "Using configWatcher service for #{@path}" }
             WatchService::CONFIG_WATCHER_FILTER
           end

  start = Time.now
  sleep 0.1 until (@watch_service = OSGi.service(service_name, filter:)) || Time.now - start > 2

  unless @watch_service
    logger.warn("Watch service is not ready in time. #{@path} will not be monitored!")
    return
  end

  @watch_service.register_listener(self, java_path, @subdirs)
  logger.trace { "Registered watch service listener for #{@path} including subdirs: #{@subdirs}" }
end

#deactivateObject

Unregister ourself as a listener and remove the watch service



81
82
83
84
85
86
87
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 81

def deactivate
  @watch_service&.unregister_listener(self)
  return unless @custom_watcher

  WatchHandler.factory.remove_watch_service(@custom_watcher)
  logger.trace { "Removed watch service #{@custom_watcher} for #{@path}" }
end

#processWatchEvent(kind, path) ⇒ Object

Invoked by the WatchService when a watch event occurs

Parameters:

  • kind (org.openhab.core.service.WatchService.Kind)

    WatchService event kind

  • path (java.nio.file.Path)

    The path that had an event



92
93
94
95
96
97
98
99
100
# File 'lib/openhab/dsl/rules/triggers/watch/watch_handler.rb', line 92

def processWatchEvent(kind, path) # rubocop:disable Naming/MethodName
  logger.trace { "processWatchEvent triggered #{path} #{kind} #{@types}" }
  return unless @types.include?(kind)

  # OH4 WatchService feeds us a relative path,
  # but just in case its implementation changes in the future
  path = path.absolute? ? Pathname.new(path.to_s) : @path + path.to_s
  @block.call(Events::WatchEvent.new(EVENT_TO_SYMBOL[kind], path))
end