Adapt addons to core watch service changes (#14004)

Signed-off-by: Jan N. Klug <github@klug.nrw>
This commit is contained in:
J-N-K
2023-02-13 16:37:57 +01:00
committed by GitHub
parent ed7159c780
commit d613641bbd
27 changed files with 216 additions and 187 deletions

View File

@@ -32,6 +32,7 @@ import org.openhab.core.automation.module.script.ScriptDependencyTracker;
import org.openhab.core.automation.module.script.ScriptEngineFactory;
import org.openhab.core.automation.module.script.ScriptExtensionManagerWrapper;
import org.openhab.core.config.core.ConfigurableService;
import org.openhab.core.service.WatchService;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
@@ -57,9 +58,9 @@ public class JRubyScriptEngineFactory extends AbstractScriptEngineFactory {
private final javax.script.ScriptEngineFactory factory = new org.jruby.embed.jsr223.JRubyEngineFactory();
private final List<String> scriptTypes = Stream.concat(Objects.requireNonNull(factory.getExtensions()).stream(),
Objects.requireNonNull(factory.getMimeTypes()).stream()).collect(Collectors.toUnmodifiableList());
Objects.requireNonNull(factory.getMimeTypes()).stream()).toList();
private JRubyDependencyTracker jrubyDependencyTracker;
private final JRubyDependencyTracker jrubyDependencyTracker;
// Adds $ in front of a set of variables so that Ruby recognizes them as global
// variables
@@ -73,8 +74,9 @@ public class JRubyScriptEngineFactory extends AbstractScriptEngineFactory {
}
@Activate
public JRubyScriptEngineFactory(Map<String, Object> config) {
jrubyDependencyTracker = new JRubyDependencyTracker(this);
public JRubyScriptEngineFactory(@Reference(target = WatchService.CONFIG_WATCHER_FILTER) WatchService watchService,
Map<String, Object> config) {
jrubyDependencyTracker = new JRubyDependencyTracker(watchService, this);
modified(config);
}

View File

@@ -12,6 +12,7 @@
*/
package org.openhab.automation.jrubyscripting.internal.watch;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -22,7 +23,7 @@ import java.util.function.Consumer;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.automation.jrubyscripting.internal.JRubyScriptEngineFactory;
import org.openhab.core.automation.module.script.ScriptDependencyTracker;
import org.openhab.core.service.AbstractWatchService;
import org.openhab.core.service.WatchService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -30,6 +31,7 @@ import org.slf4j.LoggerFactory;
* Tracks Ruby dependencies
*
* @author Cody Cutrer - Initial contribution
* @author Jan N. Klug - Refactored to new WatchService
*/
@NonNullByDefault
public class JRubyDependencyTracker implements ScriptDependencyTracker {
@@ -40,29 +42,27 @@ public class JRubyDependencyTracker implements ScriptDependencyTracker {
private final BidiSetBag<String, String> scriptToLibs = new BidiSetBag<>();
private final JRubyScriptEngineFactory scriptEngineFactory;
private final List<AbstractWatchService> dependencyWatchServices = new ArrayList<>();
private final List<JRubyWatchService> dependencyWatchServices = new ArrayList<>();
private final WatchService watchService;
public JRubyDependencyTracker(final JRubyScriptEngineFactory scriptEngineFactory) {
public JRubyDependencyTracker(final WatchService watchService, final JRubyScriptEngineFactory scriptEngineFactory) {
this.watchService = watchService;
this.scriptEngineFactory = scriptEngineFactory;
}
public void activate() {
String gemHome = scriptEngineFactory.getGemHome();
if (!gemHome.isEmpty()) {
dependencyWatchServices.add(new JRubyGemWatchService(gemHome, this));
}
for (String libPath : scriptEngineFactory.getRubyLibPaths()) {
dependencyWatchServices.add(new JRubyLibWatchService(libPath, this));
}
for (AbstractWatchService dependencyWatchService : dependencyWatchServices) {
dependencyWatchService.activate();
dependencyWatchServices.add(new JRubyGemWatchService(watchService, gemHome, this));
}
List<Path> libPaths = scriptEngineFactory.getRubyLibPaths().stream().map(Path::of).toList();
dependencyWatchServices.add(new JRubyLibWatchService(watchService, libPaths, this));
dependencyWatchServices.forEach(JRubyWatchService::activate);
}
public void deactivate() {
for (AbstractWatchService dependencyWatchService : dependencyWatchServices) {
dependencyWatchService.deactivate();
}
dependencyWatchServices.forEach(JRubyWatchService::deactivate);
dependencyWatchServices.clear();
}

View File

@@ -12,47 +12,45 @@
*/
package org.openhab.automation.jrubyscripting.internal.watch;
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.util.Arrays;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.service.AbstractWatchService;
import org.openhab.core.service.WatchService;
/**
* Watches a gem home
*
* @author Cody Cutrer - Initial contribution
* @author Jan N. Klug - Refactored to new WatchService
*/
@NonNullByDefault
public class JRubyGemWatchService extends AbstractWatchService {
public class JRubyGemWatchService implements JRubyWatchService, WatchService.WatchEventListener {
private static final String GEMSPEC = ".gemspec";
private final WatchService watchService;
private final Path path;
private JRubyDependencyTracker dependencyTracker;
JRubyGemWatchService(String path, JRubyDependencyTracker dependencyTracker) {
super(path);
JRubyGemWatchService(WatchService watchService, String path, JRubyDependencyTracker dependencyTracker) {
this.watchService = watchService;
this.dependencyTracker = dependencyTracker;
this.path = Path.of(path);
}
@Override
protected boolean watchSubDirectories() {
return true;
public void activate() {
watchService.registerListener(this, path);
}
@Override
protected WatchEvent.Kind<?> @Nullable [] getWatchEventKinds(Path path) {
return new WatchEvent.Kind<?>[] { ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY };
public void deactivate() {
watchService.unregisterListener(this);
}
@Override
protected void processWatchEvent(WatchEvent<?> watchEvent, WatchEvent.Kind<?> kind, Path path) {
public void processWatchEvent(WatchService.Kind kind, Path path) {
String file = path.toFile().getName();
if (file.endsWith(GEMSPEC)) {
// This seems really lazy, but you can't definitively tell the name

View File

@@ -12,47 +12,48 @@
*/
package org.openhab.automation.jrubyscripting.internal.watch;
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import static org.openhab.core.service.WatchService.Kind.*;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.service.AbstractWatchService;
import org.openhab.core.service.WatchService;
import org.openhab.core.service.WatchService.Kind;
/**
* Watches a Ruby lib dir
*
* @author Cody Cutrer - Initial contribution
* @author Jan N. Klug - Refactored to new WatchService
*/
@NonNullByDefault
public class JRubyLibWatchService extends AbstractWatchService {
private JRubyDependencyTracker dependencyTracker;
public class JRubyLibWatchService implements JRubyWatchService, WatchService.WatchEventListener {
private final JRubyDependencyTracker dependencyTracker;
private final WatchService watchService;
private final List<Path> paths;
JRubyLibWatchService(String path, JRubyDependencyTracker dependencyTracker) {
super(path);
JRubyLibWatchService(WatchService watchService, List<Path> paths, JRubyDependencyTracker dependencyTracker) {
this.watchService = watchService;
this.dependencyTracker = dependencyTracker;
this.paths = paths;
}
@Override
protected boolean watchSubDirectories() {
return true;
public void activate() {
watchService.registerListener(this, paths);
}
@Override
protected WatchEvent.Kind<?> @Nullable [] getWatchEventKinds(Path path) {
return new WatchEvent.Kind<?>[] { ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY };
public void deactivate() {
watchService.unregisterListener(this);
}
@Override
protected void processWatchEvent(WatchEvent<?> watchEvent, WatchEvent.Kind<?> kind, Path path) {
public void processWatchEvent(Kind kind, Path path) {
File file = path.toFile();
if (!file.isHidden() && (kind.equals(ENTRY_DELETE)
|| (file.canRead() && (kind.equals(ENTRY_CREATE) || kind.equals(ENTRY_MODIFY))))) {
if (!file.isHidden() && (kind == DELETE || (file.canRead() && (kind == CREATE || kind == MODIFY)))) {
dependencyTracker.dependencyChanged(file.getPath());
}
}

View File

@@ -25,6 +25,7 @@ import org.openhab.core.automation.module.script.rulesupport.loader.AbstractScri
import org.openhab.core.automation.module.script.rulesupport.loader.ScriptFileWatcher;
import org.openhab.core.service.ReadyService;
import org.openhab.core.service.StartLevelService;
import org.openhab.core.service.WatchService;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
@@ -36,6 +37,7 @@ import org.slf4j.LoggerFactory;
* Monitors <openHAB-conf>/automation/ruby for Ruby files, but not libraries in lib or gems
*
* @author Cody Cutrer - Initial contribution
* @author Jan N. Klug - Refactored to new WatchService
*/
@Component(immediate = true, service = { ScriptFileWatcher.class, ScriptDependencyTracker.Listener.class })
@NonNullByDefault
@@ -50,8 +52,9 @@ public class JRubyScriptFileWatcher extends AbstractScriptFileWatcher {
public JRubyScriptFileWatcher(final @Reference ScriptEngineManager manager,
final @Reference ReadyService readyService, final @Reference StartLevelService startLevelService,
final @Reference(target = "(" + Constants.SERVICE_PID
+ "=org.openhab.automation.jrubyscripting)") ScriptEngineFactory scriptEngineFactory) {
super(manager, readyService, startLevelService, FILE_DIRECTORY);
+ "=org.openhab.automation.jrubyscripting)") ScriptEngineFactory scriptEngineFactory,
final @Reference(target = WatchService.CONFIG_WATCHER_FILTER) WatchService watchService) {
super(watchService, manager, readyService, startLevelService, FILE_DIRECTORY, true);
this.scriptEngineFactory = (JRubyScriptEngineFactory) scriptEngineFactory;
}

View File

@@ -0,0 +1,34 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.automation.jrubyscripting.internal.watch;
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
* The {@link JRubyWatchService} is an interface for controlling internal watch services
*
* @author Jan N. Klug - Initial contribution
*/
@NonNullByDefault
public interface JRubyWatchService {
/**
* start watching
*/
void activate();
/**
* stop watching
*/
void deactivate();
}