From a6d93c1cbc2dfa2340f188e29183c81151ead0e1 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sat, 17 Jun 2023 10:06:56 +0200 Subject: [PATCH 01/17] Add a YAML file provider for semantic tags Files in folder conf/tags are loaded by this provider. Related to #3619 Signed-off-by: Laurent Garnier --- .../internal/config/yaml/YamlSemanticTag.java | 61 ++++++ .../config/yaml/YamlSemanticTagProvider.java | 125 +++++++++++ .../config/yaml/YamlSemanticTags.java | 44 ++++ .../semantics/model/yaml/YamlElement.java | 25 +++ .../core/semantics/model/yaml/YamlFile.java | 50 +++++ .../model/yaml/YamlModelListener.java | 39 ++++ .../model/yaml/YamlModelRepository.java | 202 ++++++++++++++++++ .../model/yaml/YamlParseException.java | 39 ++++ .../openhab-core/src/main/feature/feature.xml | 1 + 9 files changed, 586 insertions(+) create mode 100644 bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTag.java create mode 100644 bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTagProvider.java create mode 100644 bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTags.java create mode 100644 bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlElement.java create mode 100644 bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlFile.java create mode 100644 bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelListener.java create mode 100644 bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelRepository.java create mode 100644 bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlParseException.java diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTag.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTag.java new file mode 100644 index 00000000000..ff3c11dcd1c --- /dev/null +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTag.java @@ -0,0 +1,61 @@ +/** + * 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.core.semantics.internal.config.yaml; + +import java.util.List; +import java.util.Objects; + +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.semantics.model.yaml.YamlElement; +import org.openhab.core.semantics.model.yaml.YamlParseException; + +/** + * The {@link YamlSemanticTag} is a data transfer object used to serialize a semantic tag + * in a YAML configuration file. + * + * @author Laurent Garnier - Initial contribution + */ +public class YamlSemanticTag implements YamlElement { + + public String uid; + public String label; + public String description; + public List synonyms; + + public YamlSemanticTag() { + } + + @Override + public String getId() { + return uid; + } + + @Override + public void checkValidity() throws YamlParseException { + if (uid == null) { + throw new YamlParseException("uid missing"); + } + } + + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) { + return true; + } else if (obj == null || getClass() != obj.getClass()) { + return false; + } + YamlSemanticTag that = (YamlSemanticTag) obj; + return Objects.equals(uid, that.uid) && Objects.equals(label, that.label) + && Objects.equals(description, that.description) && Objects.equals(synonyms, that.synonyms); + } +} diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTagProvider.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTagProvider.java new file mode 100644 index 00000000000..5f79737ee11 --- /dev/null +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTagProvider.java @@ -0,0 +1,125 @@ +/** + * 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.core.semantics.internal.config.yaml; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.common.registry.AbstractProvider; +import org.openhab.core.semantics.SemanticTag; +import org.openhab.core.semantics.SemanticTagImpl; +import org.openhab.core.semantics.SemanticTagProvider; +import org.openhab.core.semantics.SemanticTagRegistry; +import org.openhab.core.semantics.model.yaml.YamlElement; +import org.openhab.core.semantics.model.yaml.YamlFile; +import org.openhab.core.semantics.model.yaml.YamlModelListener; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * {@link YamlSemanticTagProvider} is an OSGi service, that allows to define semantic tags + * in YAML configuration files in folder conf/tags. + * Files can be added, updated or removed at runtime. + * These semantic tags are automatically exposed to the {@link SemanticTagRegistry}. + * + * @author Laurent Garnier - Initial contribution + */ +@NonNullByDefault +@Component(immediate = true, service = { SemanticTagProvider.class, YamlSemanticTagProvider.class, + YamlModelListener.class }) +public class YamlSemanticTagProvider extends AbstractProvider + implements SemanticTagProvider, YamlModelListener { + + private final Logger logger = LoggerFactory.getLogger(YamlSemanticTagProvider.class); + + private final List tags = new ArrayList<>(); + + @Activate + public YamlSemanticTagProvider() { + } + + @Deactivate + public void deactivate() { + tags.clear(); + } + + @Override + public Collection getAll() { + return tags.stream().sorted(Comparator.comparing(SemanticTag::getUID)).toList(); + } + + @Override + public String getRootName() { + return "tags"; + } + + @Override + public Class getFileClass() { + return YamlSemanticTags.class; + } + + @Override + public Class getElementClass() { + return YamlSemanticTag.class; + } + + @Override + public void addedModel(String modelName, List elements) { + List added = elements.stream().map(e -> mapSemanticTag((YamlSemanticTag) e)) + .sorted(Comparator.comparing(SemanticTag::getUID)).toList(); + tags.addAll(added); + added.forEach(t -> { + logger.debug("model {} added tag {}", modelName, t.getUID()); + notifyListenersAboutAddedElement(t); + }); + } + + @Override + public void updatedModel(String modelName, List elements) { + List updated = elements.stream().map(e -> mapSemanticTag((YamlSemanticTag) e)).toList(); + updated.forEach(t -> { + tags.stream().filter(tag -> tag.getUID().equals(t.getUID())).findFirst().ifPresentOrElse(oldTag -> { + tags.remove(oldTag); + tags.add(t); + logger.debug("model {} updated tag {}", modelName, t.getUID()); + notifyListenersAboutUpdatedElement(oldTag, t); + }, () -> logger.debug("model {} tag {} not found", modelName, t.getUID())); + }); + } + + @Override + public void removedModel(String modelName, List elements) { + List removed = elements.stream().map(e -> mapSemanticTag((YamlSemanticTag) e)) + .sorted(Comparator.comparing(SemanticTag::getUID).reversed()).toList(); + removed.forEach(t -> { + tags.stream().filter(tag -> tag.getUID().equals(t.getUID())).findFirst().ifPresentOrElse(oldTag -> { + tags.remove(oldTag); + logger.debug("model {} removed tag {}", modelName, t.getUID()); + notifyListenersAboutRemovedElement(oldTag); + }, () -> logger.debug("model {} tag {} not found", modelName, t.getUID())); + }); + } + + private SemanticTag mapSemanticTag(YamlSemanticTag tagDTO) { + if (tagDTO.uid == null) { + throw new IllegalArgumentException("The argument 'tagDTO.uid' must not be null."); + } + return new SemanticTagImpl(tagDTO.uid, tagDTO.label, tagDTO.description, tagDTO.synonyms); + } +} diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTags.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTags.java new file mode 100644 index 00000000000..3f44af0c5ca --- /dev/null +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTags.java @@ -0,0 +1,44 @@ +/** + * 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.core.semantics.internal.config.yaml; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.semantics.model.yaml.YamlElement; +import org.openhab.core.semantics.model.yaml.YamlFile; +import org.openhab.core.semantics.model.yaml.YamlParseException; + +/** + * The {@link YamlSemanticTags} is a data transfer object used to serialize a list of semantic tags + * in a YAML configuration file. + * + * @author Laurent Garnier - Initial contribution + */ +@NonNullByDefault +public class YamlSemanticTags extends YamlFile { + + public List tags = List.of(); + + @Override + public List getElements() { + return tags; + } + + @Override + protected void checkVersion() throws YamlParseException { + if (version != 1) { + throw new YamlParseException("Version 1 required; please convert your file"); + } + } +} diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlElement.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlElement.java new file mode 100644 index 00000000000..e994732d3cd --- /dev/null +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlElement.java @@ -0,0 +1,25 @@ +/** + * 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.core.semantics.model.yaml; + +/** + * The {@link YamlElement} interface offers an identifier to any element defined in a YAML configuration file. + * + * @author Laurent Garnier - Initial contribution + */ +public interface YamlElement { + + String getId(); + + void checkValidity() throws YamlParseException; +} diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlFile.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlFile.java new file mode 100644 index 00000000000..889feeb20a9 --- /dev/null +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlFile.java @@ -0,0 +1,50 @@ +/** + * 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.core.semantics.model.yaml; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link YamlFile} is the DTO base class used to map a YAML configuration file. + * + * A YAML configuration file consists of a version and a list of elements. + * + * @author Laurent Garnier - Initial contribution + */ +@NonNullByDefault +public abstract class YamlFile { + + public int version; + + public abstract List getElements(); + + protected abstract void checkVersion() throws YamlParseException; + + public void checkValidity() throws YamlParseException { + checkVersion(); + List elts = getElements(); + long nbDistinctIds = elts.stream().map(YamlElement::getId).distinct().count(); + if (nbDistinctIds < elts.size()) { + throw new YamlParseException((elts.size() - nbDistinctIds + 1) + " elements with same ids"); + } + for (int i = 0; i < elts.size(); i++) { + try { + elts.get(i).checkValidity(); + } catch (YamlParseException e) { + throw new YamlParseException("Error in element " + (i + 1) + ": " + e.getMessage()); + } + } + } +} diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelListener.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelListener.java new file mode 100644 index 00000000000..6a49659b659 --- /dev/null +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelListener.java @@ -0,0 +1,39 @@ +/** + * 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.core.semantics.model.yaml; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link YamlModelListener} interface is responsible for managing a particular model + * with data processed from YAML configuration files. + * + * @author Laurent Garnier - Initial contribution + */ +@NonNullByDefault +public interface YamlModelListener { + + void addedModel(String modelName, List elements); + + void updatedModel(String modelName, List elements); + + void removedModel(String modelName, List elements); + + String getRootName(); + + Class getFileClass(); + + Class getElementClass(); +} diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelRepository.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelRepository.java new file mode 100644 index 00000000000..e1f8f75ffd4 --- /dev/null +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelRepository.java @@ -0,0 +1,202 @@ +/** + * 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.core.semantics.model.yaml; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.service.WatchService; +import org.openhab.core.service.WatchService.Kind; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; + +/** + * The {@link YamlModelRepository} is an OSGi service, that encapsulates all YAML file processing + * including file monitoring to detect created, updated and removed YAML configuration files. + * Data processed from these files are consumed by registered OSGi services that implement {@link YamlModelListener}. + * + * @author Laurent Garnier - Initial contribution + */ +@NonNullByDefault +@Component(immediate = true) +public class YamlModelRepository implements WatchService.WatchEventListener { + + private final Logger logger = LoggerFactory.getLogger(YamlModelRepository.class); + + private final WatchService watchService; + private final List watchPaths = new CopyOnWriteArrayList<>(); + private final ObjectMapper yamlReader; + private final List> listeners = new CopyOnWriteArrayList<>(); + private final Map> objects = new ConcurrentHashMap<>(); + + @Activate + public YamlModelRepository(@Reference(target = WatchService.CONFIG_WATCHER_FILTER) WatchService watchService) { + this.watchService = watchService; + this.yamlReader = new ObjectMapper(new YAMLFactory()); + yamlReader.findAndRegisterModules(); + } + + @Deactivate + public void deactivate() { + objects.clear(); + } + + @Override + public synchronized void processWatchEvent(Kind kind, Path path) { + // path parameter is currently wrong ! It is a path in userdata folder + // Temporary workaround: build a path in tags folder + Path fixecPath = watchService.getWatchPath().resolve("tags").resolve(path.getFileName()); + logger.debug("processWatchEvent {} path={} fixecPath={}", kind, path.toFile().getAbsolutePath(), + fixecPath.toFile().getAbsolutePath()); + YamlModelListener listener = findModelListener(fixecPath); + if (listener == null) { + logger.warn("No YAML file consumer available for {}; file is ignored", + fixecPath.toFile().getAbsolutePath()); + return; + } + processWatchEvent(kind, fixecPath, listener); + } + + private void processWatchEvent(Kind kind, Path path, YamlModelListener listener) { + logger.debug("processWatchEvent {} {} {}", kind, listener.getRootName(), path.toFile().getAbsolutePath()); + if (Files.isDirectory(path) || path.toFile().isHidden() || !path.toFile().getName().endsWith(".yaml")) { + logger.debug("{} is ignored", path.toFile().getAbsolutePath()); + return; + } + Map oldObjects; + Map newObjects; + if (kind == WatchService.Kind.DELETE) { + newObjects = Map.of(); + + List oldListObjects = objects.remove(path); + if (oldListObjects == null) { + oldListObjects = List.of(); + } + oldObjects = oldListObjects.stream().collect(Collectors.toMap(YamlElement::getId, obj -> obj)); + } else { + YamlFile yamlData; + try { + yamlData = readYamlFile(path, listener.getFileClass()); + } catch (YamlParseException e) { + logger.warn("Failed to parse Yaml file {} with DTO class {}: {}", path.toFile().getAbsolutePath(), + listener.getFileClass().getName(), e.getMessage()); + return; + } + List newListObjects = yamlData.getElements(); + newObjects = newListObjects.stream().collect(Collectors.toMap(YamlElement::getId, obj -> obj)); + + List oldListObjects = objects.get(path); + if (oldListObjects == null) { + oldListObjects = List.of(); + } + oldObjects = oldListObjects.stream().collect(Collectors.toMap(YamlElement::getId, obj -> obj)); + + objects.put(path, newListObjects); + } + + String modelName = path.toFile().getName(); + modelName = modelName.substring(0, modelName.indexOf(".yaml")); + List listElts; + listElts = oldObjects.entrySet().stream() + .filter(entry -> entry.getValue().getClass().equals(listener.getElementClass()) + && !newObjects.containsKey(entry.getKey())) + .map(entry -> entry.getValue()).toList(); + if (!listElts.isEmpty()) { + listener.removedModel(modelName, listElts); + } + + listElts = newObjects.entrySet().stream() + .filter(entry -> entry.getValue().getClass().equals(listener.getElementClass()) + && !oldObjects.containsKey(entry.getKey())) + .map(entry -> entry.getValue()).toList(); + if (!listElts.isEmpty()) { + listener.addedModel(modelName, listElts); + } + + // Object is ignored if unchanged + listElts = newObjects.entrySet().stream() + .filter(entry -> entry.getValue().getClass().equals(listener.getElementClass()) + && oldObjects.containsKey(entry.getKey()) + && !entry.getValue().equals(oldObjects.get(entry.getKey()))) + .map(entry -> entry.getValue()).toList(); + if (!listElts.isEmpty()) { + listener.updatedModel(modelName, listElts); + } + } + + private @Nullable YamlModelListener findModelListener(Path path) { + for (YamlModelListener listener : listeners) { + if (path.startsWith(watchService.getWatchPath().resolve(listener.getRootName()))) { + return listener; + } + } + return null; + } + + private YamlFile readYamlFile(Path path, Class dtoClass) throws YamlParseException { + logger.debug("readYamlFile {} with {}", path.toFile().getAbsolutePath(), dtoClass.getName()); + try { + YamlFile dto = yamlReader.readValue(path.toFile(), dtoClass); + dto.checkValidity(); + return dto; + } catch (IOException e) { + throw new YamlParseException(e); + } + } + + @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC) + protected void addYamlModelListener(YamlModelListener listener) { + logger.debug("addYamlModelListener {}", listener.getRootName()); + listeners.add(listener); + + Path watchPath = watchService.getWatchPath().resolve(listener.getRootName()); + watchPaths.add(watchPath); + watchService.unregisterListener(this); + watchService.registerListener(this, watchPaths); + + // Load all existing YAML files + try (Stream stream = Files.walk(watchPath)) { + stream.forEach(path -> processWatchEvent(Kind.CREATE, path, listener)); + } catch (IOException e) { + } + } + + protected void removeYamlModelListener(YamlModelListener listener) { + listeners.remove(listener); + + Path watchPath = watchService.getWatchPath().resolve(listener.getRootName()); + watchPaths.remove(watchPath); + watchService.unregisterListener(this); + if (!watchPaths.isEmpty()) { + watchService.registerListener(this, watchPaths); + } + } +} diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlParseException.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlParseException.java new file mode 100644 index 00000000000..95894fdcc2f --- /dev/null +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlParseException.java @@ -0,0 +1,39 @@ +/** + * 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.core.semantics.model.yaml; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link YamlParseException} is used when an error is detected when parsing the content + * of a YAML configuration file. + * + * @author Laurent Garnier - Initial contribution + */ +@NonNullByDefault +public class YamlParseException extends Exception { + + private static final long serialVersionUID = 1L; + + public YamlParseException(String message) { + super(message); + } + + public YamlParseException(Throwable cause) { + super(cause); + } + + public YamlParseException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/features/karaf/openhab-core/src/main/feature/feature.xml b/features/karaf/openhab-core/src/main/feature/feature.xml index 615a415ab7b..ba8ed3ae829 100644 --- a/features/karaf/openhab-core/src/main/feature/feature.xml +++ b/features/karaf/openhab-core/src/main/feature/feature.xml @@ -55,6 +55,7 @@ mvn:org.openhab.core.bundles/org.openhab.core.persistence/${project.version} mvn:org.openhab.core.bundles/org.openhab.core.semantics/${project.version} openhab.tp-asm + openhab.tp-jackson mvn:org.openhab.core.bundles/org.openhab.core.thing/${project.version} mvn:org.openhab.core.bundles/org.openhab.core.transform/${project.version} mvn:org.openhab.core.bundles/org.openhab.core.audio/${project.version} From 13bd2d231d032fd6b4c9a5a707c12a293e5f9328 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Thu, 29 Jun 2023 01:03:25 +0200 Subject: [PATCH 02/17] Try to fix itests build Signed-off-by: Laurent Garnier --- itests/org.openhab.core.io.rest.core.tests/itest.bndrun | 1 + itests/org.openhab.core.model.item.tests/itest.bndrun | 1 + itests/org.openhab.core.model.rule.tests/itest.bndrun | 1 + itests/org.openhab.core.model.script.tests/itest.bndrun | 1 + itests/org.openhab.core.model.thing.tests/itest.bndrun | 1 + 5 files changed, 5 insertions(+) diff --git a/itests/org.openhab.core.io.rest.core.tests/itest.bndrun b/itests/org.openhab.core.io.rest.core.tests/itest.bndrun index f2d2f06a979..5104bea137c 100644 --- a/itests/org.openhab.core.io.rest.core.tests/itest.bndrun +++ b/itests/org.openhab.core.io.rest.core.tests/itest.bndrun @@ -67,6 +67,7 @@ Fragment-Host: org.openhab.core.io.rest.core org.openhab.core.test;version='[4.0.0,4.0.1)',\ org.openhab.core.thing;version='[4.0.0,4.0.1)',\ org.openhab.core.transform;version='[4.0.0,4.0.1)',\ + com.fasterxml.jackson.dataformat;version='[2.14.1,2.14.2)',\ io.methvin.directory-watcher;version='[0.17.1,0.17.2)',\ com.sun.jna;version='[5.12.1,5.12.2)',\ com.fasterxml.woodstox.woodstox-core;version='[6.4.0,6.4.1)',\ diff --git a/itests/org.openhab.core.model.item.tests/itest.bndrun b/itests/org.openhab.core.model.item.tests/itest.bndrun index 19c699af908..5d533388137 100644 --- a/itests/org.openhab.core.model.item.tests/itest.bndrun +++ b/itests/org.openhab.core.model.item.tests/itest.bndrun @@ -79,6 +79,7 @@ Fragment-Host: org.openhab.core.model.item org.openhab.core.thing;version='[4.0.0,4.0.1)',\ org.openhab.core.transform;version='[4.0.0,4.0.1)',\ org.openhab.core.voice;version='[4.0.0,4.0.1)',\ + com.fasterxml.jackson.dataformat;version='[2.14.1,2.14.2)',\ io.methvin.directory-watcher;version='[0.17.1,0.17.2)',\ com.sun.jna;version='[5.12.1,5.12.2)',\ org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ diff --git a/itests/org.openhab.core.model.rule.tests/itest.bndrun b/itests/org.openhab.core.model.rule.tests/itest.bndrun index 0956d07ece1..ad82cb21066 100644 --- a/itests/org.openhab.core.model.rule.tests/itest.bndrun +++ b/itests/org.openhab.core.model.rule.tests/itest.bndrun @@ -83,6 +83,7 @@ Fragment-Host: org.openhab.core.model.rule.runtime org.openhab.core.thing;version='[4.0.0,4.0.1)',\ org.openhab.core.transform;version='[4.0.0,4.0.1)',\ org.openhab.core.voice;version='[4.0.0,4.0.1)',\ + com.fasterxml.jackson.dataformat;version='[2.14.1,2.14.2)',\ io.methvin.directory-watcher;version='[0.17.1,0.17.2)',\ com.sun.jna;version='[5.12.1,5.12.2)',\ org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ diff --git a/itests/org.openhab.core.model.script.tests/itest.bndrun b/itests/org.openhab.core.model.script.tests/itest.bndrun index b9de3468ee1..dff6e8b4b94 100644 --- a/itests/org.openhab.core.model.script.tests/itest.bndrun +++ b/itests/org.openhab.core.model.script.tests/itest.bndrun @@ -81,6 +81,7 @@ Fragment-Host: org.openhab.core.model.script org.openhab.core.thing;version='[4.0.0,4.0.1)',\ org.openhab.core.transform;version='[4.0.0,4.0.1)',\ org.openhab.core.voice;version='[4.0.0,4.0.1)',\ + com.fasterxml.jackson.dataformat;version='[2.14.1,2.14.2)',\ io.methvin.directory-watcher;version='[0.17.1,0.17.2)',\ com.sun.jna;version='[5.12.1,5.12.2)',\ org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ diff --git a/itests/org.openhab.core.model.thing.tests/itest.bndrun b/itests/org.openhab.core.model.thing.tests/itest.bndrun index 25c8c33ec06..6921c9c262c 100644 --- a/itests/org.openhab.core.model.thing.tests/itest.bndrun +++ b/itests/org.openhab.core.model.thing.tests/itest.bndrun @@ -82,6 +82,7 @@ Fragment-Host: org.openhab.core.model.thing org.openhab.core.thing;version='[4.0.0,4.0.1)',\ org.openhab.core.transform;version='[4.0.0,4.0.1)',\ org.openhab.core.voice;version='[4.0.0,4.0.1)',\ + com.fasterxml.jackson.dataformat;version='[2.14.1,2.14.2)',\ io.methvin.directory-watcher;version='[0.17.1,0.17.2)',\ com.sun.jna;version='[5.12.1,5.12.2)',\ org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ From 3d3439956e9c998e7af06b36dd696a241f6e3fbf Mon Sep 17 00:00:00 2001 From: "Jan N. Klug" Date: Sat, 8 Jul 2023 14:08:15 +0200 Subject: [PATCH 03/17] This should fix your watch service issues Signed-off-by: Jan N. Klug --- .../model/yaml/YamlModelRepository.java | 94 ++++++++----------- 1 file changed, 38 insertions(+), 56 deletions(-) diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelRepository.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelRepository.java index e1f8f75ffd4..fa3408be2d9 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelRepository.java +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelRepository.java @@ -17,13 +17,13 @@ import java.nio.file.Path; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Collectors; import java.util.stream.Stream; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; import org.openhab.core.service.WatchService; import org.openhab.core.service.WatchService.Kind; import org.osgi.service.component.annotations.Activate; @@ -52,51 +52,47 @@ public class YamlModelRepository implements WatchService.WatchEventListener { private final Logger logger = LoggerFactory.getLogger(YamlModelRepository.class); private final WatchService watchService; - private final List watchPaths = new CopyOnWriteArrayList<>(); + private final Path watchPath; private final ObjectMapper yamlReader; - private final List> listeners = new CopyOnWriteArrayList<>(); - private final Map> objects = new ConcurrentHashMap<>(); + + private final Map>> listeners = new ConcurrentHashMap<>(); + private final Map> objects = new ConcurrentHashMap<>(); @Activate public YamlModelRepository(@Reference(target = WatchService.CONFIG_WATCHER_FILTER) WatchService watchService) { this.watchService = watchService; this.yamlReader = new ObjectMapper(new YAMLFactory()); yamlReader.findAndRegisterModules(); + + watchService.registerListener(this, Path.of("")); + watchPath = watchService.getWatchPath(); } @Deactivate public void deactivate() { - objects.clear(); + watchService.unregisterListener(this); } @Override public synchronized void processWatchEvent(Kind kind, Path path) { - // path parameter is currently wrong ! It is a path in userdata folder - // Temporary workaround: build a path in tags folder - Path fixecPath = watchService.getWatchPath().resolve("tags").resolve(path.getFileName()); - logger.debug("processWatchEvent {} path={} fixecPath={}", kind, path.toFile().getAbsolutePath(), - fixecPath.toFile().getAbsolutePath()); - YamlModelListener listener = findModelListener(fixecPath); - if (listener == null) { - logger.warn("No YAML file consumer available for {}; file is ignored", - fixecPath.toFile().getAbsolutePath()); + Path fullPath = watchPath.resolve(path); + String dirName = path.subpath(0, 1).toString(); + + if (Files.isDirectory(fullPath) || fullPath.toFile().isHidden() || !fullPath.toString().endsWith(".yaml")) { + logger.debug("Ignored {}", fullPath); return; } - processWatchEvent(kind, fixecPath, listener); + + getListeners(dirName).forEach(listener -> processWatchEvent(dirName, kind, fullPath, listener)); } - private void processWatchEvent(Kind kind, Path path, YamlModelListener listener) { - logger.debug("processWatchEvent {} {} {}", kind, listener.getRootName(), path.toFile().getAbsolutePath()); - if (Files.isDirectory(path) || path.toFile().isHidden() || !path.toFile().getName().endsWith(".yaml")) { - logger.debug("{} is ignored", path.toFile().getAbsolutePath()); - return; - } + private void processWatchEvent(String dirName, Kind kind, Path fullPath, YamlModelListener listener) { Map oldObjects; Map newObjects; if (kind == WatchService.Kind.DELETE) { newObjects = Map.of(); - List oldListObjects = objects.remove(path); + List oldListObjects = objects.remove(dirName); if (oldListObjects == null) { oldListObjects = List.of(); } @@ -104,31 +100,31 @@ private void processWatchEvent(Kind kind, Path path, YamlModelListener listen } else { YamlFile yamlData; try { - yamlData = readYamlFile(path, listener.getFileClass()); + yamlData = readYamlFile(fullPath, listener.getFileClass()); } catch (YamlParseException e) { - logger.warn("Failed to parse Yaml file {} with DTO class {}: {}", path.toFile().getAbsolutePath(), + logger.warn("Failed to parse Yaml file {} with DTO class {}: {}", fullPath, listener.getFileClass().getName(), e.getMessage()); return; } List newListObjects = yamlData.getElements(); newObjects = newListObjects.stream().collect(Collectors.toMap(YamlElement::getId, obj -> obj)); - List oldListObjects = objects.get(path); + List oldListObjects = objects.get(dirName); if (oldListObjects == null) { oldListObjects = List.of(); } oldObjects = oldListObjects.stream().collect(Collectors.toMap(YamlElement::getId, obj -> obj)); - objects.put(path, newListObjects); + objects.put(dirName, newListObjects); } - String modelName = path.toFile().getName(); + String modelName = fullPath.toFile().getName(); modelName = modelName.substring(0, modelName.indexOf(".yaml")); List listElts; listElts = oldObjects.entrySet().stream() .filter(entry -> entry.getValue().getClass().equals(listener.getElementClass()) && !newObjects.containsKey(entry.getKey())) - .map(entry -> entry.getValue()).toList(); + .map(Map.Entry::getValue).toList(); if (!listElts.isEmpty()) { listener.removedModel(modelName, listElts); } @@ -136,7 +132,7 @@ private void processWatchEvent(Kind kind, Path path, YamlModelListener listen listElts = newObjects.entrySet().stream() .filter(entry -> entry.getValue().getClass().equals(listener.getElementClass()) && !oldObjects.containsKey(entry.getKey())) - .map(entry -> entry.getValue()).toList(); + .map(Map.Entry::getValue).toList(); if (!listElts.isEmpty()) { listener.addedModel(modelName, listElts); } @@ -146,21 +142,12 @@ private void processWatchEvent(Kind kind, Path path, YamlModelListener listen .filter(entry -> entry.getValue().getClass().equals(listener.getElementClass()) && oldObjects.containsKey(entry.getKey()) && !entry.getValue().equals(oldObjects.get(entry.getKey()))) - .map(entry -> entry.getValue()).toList(); + .map(Map.Entry::getValue).toList(); if (!listElts.isEmpty()) { listener.updatedModel(modelName, listElts); } } - private @Nullable YamlModelListener findModelListener(Path path) { - for (YamlModelListener listener : listeners) { - if (path.startsWith(watchService.getWatchPath().resolve(listener.getRootName()))) { - return listener; - } - } - return null; - } - private YamlFile readYamlFile(Path path, Class dtoClass) throws YamlParseException { logger.debug("readYamlFile {} with {}", path.toFile().getAbsolutePath(), dtoClass.getName()); try { @@ -174,29 +161,24 @@ private YamlFile readYamlFile(Path path, Class dtoClass) thr @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC) protected void addYamlModelListener(YamlModelListener listener) { - logger.debug("addYamlModelListener {}", listener.getRootName()); - listeners.add(listener); - - Path watchPath = watchService.getWatchPath().resolve(listener.getRootName()); - watchPaths.add(watchPath); - watchService.unregisterListener(this); - watchService.registerListener(this, watchPaths); + String dirName = listener.getRootName(); + logger.debug("Adding model listener for {}", dirName); + getListeners(dirName).add(listener); // Load all existing YAML files - try (Stream stream = Files.walk(watchPath)) { - stream.forEach(path -> processWatchEvent(Kind.CREATE, path, listener)); - } catch (IOException e) { + try (Stream stream = Files.walk(watchPath.resolve(dirName))) { + stream.forEach(path -> processWatchEvent(dirName, Kind.CREATE, path, listener)); + } catch (IOException ignored) { } } protected void removeYamlModelListener(YamlModelListener listener) { - listeners.remove(listener); + String dirName = listener.getRootName(); + logger.debug("Removing model listener for {}", dirName); + getListeners(dirName).remove(listener); + } - Path watchPath = watchService.getWatchPath().resolve(listener.getRootName()); - watchPaths.remove(watchPath); - watchService.unregisterListener(this); - if (!watchPaths.isEmpty()) { - watchService.registerListener(this, watchPaths); - } + private List> getListeners(String dirName) { + return Objects.requireNonNull(listeners.computeIfAbsent(dirName, k -> new CopyOnWriteArrayList<>())); } } From 330b8d7c2c44adc2ddd7598855d49351efcd230e Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sun, 9 Jul 2023 11:00:25 +0200 Subject: [PATCH 04/17] Keep track of objects per file Signed-off-by: Laurent Garnier --- .../model/yaml/YamlModelRepository.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelRepository.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelRepository.java index fa3408be2d9..b9d0e6cee2e 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelRepository.java +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelRepository.java @@ -56,7 +56,7 @@ public class YamlModelRepository implements WatchService.WatchEventListener { private final ObjectMapper yamlReader; private final Map>> listeners = new ConcurrentHashMap<>(); - private final Map> objects = new ConcurrentHashMap<>(); + private final Map> objects = new ConcurrentHashMap<>(); @Activate public YamlModelRepository(@Reference(target = WatchService.CONFIG_WATCHER_FILTER) WatchService watchService) { @@ -87,12 +87,14 @@ public synchronized void processWatchEvent(Kind kind, Path path) { } private void processWatchEvent(String dirName, Kind kind, Path fullPath, YamlModelListener listener) { + logger.debug("processWatchEvent dirName={} kind={} fullPath={} listener={}", dirName, kind, fullPath, + listener.getClass().getSimpleName()); Map oldObjects; Map newObjects; if (kind == WatchService.Kind.DELETE) { newObjects = Map.of(); - List oldListObjects = objects.remove(dirName); + List oldListObjects = objects.remove(fullPath); if (oldListObjects == null) { oldListObjects = List.of(); } @@ -109,13 +111,13 @@ private void processWatchEvent(String dirName, Kind kind, Path fullPath, YamlMod List newListObjects = yamlData.getElements(); newObjects = newListObjects.stream().collect(Collectors.toMap(YamlElement::getId, obj -> obj)); - List oldListObjects = objects.get(dirName); + List oldListObjects = objects.get(fullPath); if (oldListObjects == null) { oldListObjects = List.of(); } oldObjects = oldListObjects.stream().collect(Collectors.toMap(YamlElement::getId, obj -> obj)); - objects.put(dirName, newListObjects); + objects.put(fullPath, newListObjects); } String modelName = fullPath.toFile().getName(); @@ -167,7 +169,11 @@ protected void addYamlModelListener(YamlModelListener listener) { // Load all existing YAML files try (Stream stream = Files.walk(watchPath.resolve(dirName))) { - stream.forEach(path -> processWatchEvent(dirName, Kind.CREATE, path, listener)); + stream.forEach(path -> { + if (!Files.isDirectory(path) && !path.toFile().isHidden() && path.toString().endsWith(".yaml")) { + processWatchEvent(dirName, Kind.CREATE, path, listener); + } + }); } catch (IOException ignored) { } } From 62dc63c7eebcc6abeca2a918a22a71c73427b0ef Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sun, 9 Jul 2023 12:31:03 +0200 Subject: [PATCH 05/17] Move generic repository stuff to bundle org.openhab.core.model.core Signed-off-by: Laurent Garnier --- .../internal}/yaml/YamlModelRepository.java | 7 +- .../core/model/core}/yaml/YamlElement.java | 15 +++- .../core/model/core}/yaml/YamlFile.java | 29 ++++++- .../model/core/yaml/YamlModelListener.java | 75 +++++++++++++++++++ .../model/core}/yaml/YamlParseException.java | 2 +- bundles/org.openhab.core.semantics/pom.xml | 5 ++ .../internal/config/yaml/YamlSemanticTag.java | 4 +- .../config/yaml/YamlSemanticTagProvider.java | 6 +- .../config/yaml/YamlSemanticTags.java | 6 +- .../model/yaml/YamlModelListener.java | 39 ---------- 10 files changed, 135 insertions(+), 53 deletions(-) rename bundles/{org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model => org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/internal}/yaml/YamlModelRepository.java (95%) rename bundles/{org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model => org.openhab.core.model.core/src/main/java/org/openhab/core/model/core}/yaml/YamlElement.java (56%) rename bundles/{org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model => org.openhab.core.model.core/src/main/java/org/openhab/core/model/core}/yaml/YamlFile.java (63%) create mode 100644 bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlModelListener.java rename bundles/{org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model => org.openhab.core.model.core/src/main/java/org/openhab/core/model/core}/yaml/YamlParseException.java (95%) delete mode 100644 bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelListener.java diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelRepository.java b/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/internal/yaml/YamlModelRepository.java similarity index 95% rename from bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelRepository.java rename to bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/internal/yaml/YamlModelRepository.java index b9d0e6cee2e..74abfd8e33c 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelRepository.java +++ b/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/internal/yaml/YamlModelRepository.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.semantics.model.yaml; +package org.openhab.core.model.core.internal.yaml; import java.io.IOException; import java.nio.file.Files; @@ -24,6 +24,10 @@ import java.util.stream.Stream; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.model.core.yaml.YamlElement; +import org.openhab.core.model.core.yaml.YamlFile; +import org.openhab.core.model.core.yaml.YamlModelListener; +import org.openhab.core.model.core.yaml.YamlParseException; import org.openhab.core.service.WatchService; import org.openhab.core.service.WatchService.Kind; import org.osgi.service.component.annotations.Activate; @@ -73,6 +77,7 @@ public void deactivate() { watchService.unregisterListener(this); } + // The method is "synchronized" to avoid concurrent files processing @Override public synchronized void processWatchEvent(Kind kind, Path path) { Path fullPath = watchPath.resolve(path); diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlElement.java b/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlElement.java similarity index 56% rename from bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlElement.java rename to bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlElement.java index e994732d3cd..209e8605ce1 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlElement.java +++ b/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlElement.java @@ -10,16 +10,27 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.semantics.model.yaml; +package org.openhab.core.model.core.yaml; /** - * The {@link YamlElement} interface offers an identifier to any element defined in a YAML configuration file. + * The {@link YamlElement} interface offers an identifier and a check validity method + * to any element defined in a YAML configuration file. * * @author Laurent Garnier - Initial contribution */ public interface YamlElement { + /** + * Get the identifier of the YAML element + * + * @return the identifier as a string + */ String getId(); + /** + * Check that the YAML element is valid + * + * @throws YamlParseException if something is wrong + */ void checkValidity() throws YamlParseException; } diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlFile.java b/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlFile.java similarity index 63% rename from bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlFile.java rename to bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlFile.java index 889feeb20a9..29ee7720867 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlFile.java +++ b/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlFile.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.semantics.model.yaml; +package org.openhab.core.model.core.yaml; import java.util.List; @@ -26,19 +26,44 @@ @NonNullByDefault public abstract class YamlFile { + /** + * YAML file version + */ public int version; + /** + * Get the list of elements present in the YAML file. + * + * @return the list of elements + */ public abstract List getElements(); + /** + * Check that the version in the YAML file in the expected one. + * + * @throws YamlParseException if the version in the file is not the expected one + */ protected abstract void checkVersion() throws YamlParseException; + /** + * Check that the file content is valid. + * It includes the check of the version, the check of duplicated elements (same identifier) + * and the check of each element. + * + * @throws YamlParseException if something is invalid + */ public void checkValidity() throws YamlParseException { + // Checking version checkVersion(); + + // Checking duplicated elements List elts = getElements(); long nbDistinctIds = elts.stream().map(YamlElement::getId).distinct().count(); if (nbDistinctIds < elts.size()) { - throw new YamlParseException((elts.size() - nbDistinctIds + 1) + " elements with same ids"); + throw new YamlParseException("Elements with same ids detected in the file"); } + + // Checking each element for (int i = 0; i < elts.size(); i++) { try { elts.get(i).checkValidity(); diff --git a/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlModelListener.java b/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlModelListener.java new file mode 100644 index 00000000000..148dac434a4 --- /dev/null +++ b/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlModelListener.java @@ -0,0 +1,75 @@ +/** + * 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.core.model.core.yaml; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link YamlModelListener} interface is responsible for managing a particular model type + * with data processed from YAML configuration files. + * + * @author Laurent Garnier - Initial contribution + */ +@NonNullByDefault +public interface YamlModelListener { + + /** + * Method called by the model repository when elements from a model are added. + * + * @param modelName the name of the model + * @param elements the list of added elements + */ + void addedModel(String modelName, List elements); + + /** + * Method called by the model repository when elements from a model are updated. + * + * @param modelName the name of the model + * @param elements the list of updated elements + */ + void updatedModel(String modelName, List elements); + + /** + * Method called by the model repository when elements from a model are removed. + * + * @param modelName the name of the model + * @param elements the list of removed elements + */ + void removedModel(String modelName, List elements); + + /** + * Get the root name of this model type which is also the name of the root folder + * containing the user files for this model type. + * + * A path is unexpected. What is expected is for example "items" or "things". + * + * @return the model root name + */ + String getRootName(); + + /** + * Get the DTO class to be used for a file providing objects for this model type. + * + * @return the DTO file class + */ + Class getFileClass(); + + /** + * Get the DTO class to be used for each object of this model type. + * + * @return the DTO element class + */ + Class getElementClass(); +} diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlParseException.java b/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlParseException.java similarity index 95% rename from bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlParseException.java rename to bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlParseException.java index 95894fdcc2f..2adf8f9fe22 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlParseException.java +++ b/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlParseException.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.semantics.model.yaml; +package org.openhab.core.model.core.yaml; import org.eclipse.jdt.annotation.NonNullByDefault; diff --git a/bundles/org.openhab.core.semantics/pom.xml b/bundles/org.openhab.core.semantics/pom.xml index 1ebf3cec206..809e0a3afe4 100644 --- a/bundles/org.openhab.core.semantics/pom.xml +++ b/bundles/org.openhab.core.semantics/pom.xml @@ -20,6 +20,11 @@ org.openhab.core ${project.version} + + org.openhab.core.bundles + org.openhab.core.model.core + ${project.version} + org.ow2.asm asm diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTag.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTag.java index ff3c11dcd1c..e4da6e02494 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTag.java +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTag.java @@ -16,8 +16,8 @@ import java.util.Objects; import org.eclipse.jdt.annotation.Nullable; -import org.openhab.core.semantics.model.yaml.YamlElement; -import org.openhab.core.semantics.model.yaml.YamlParseException; +import org.openhab.core.model.core.yaml.YamlElement; +import org.openhab.core.model.core.yaml.YamlParseException; /** * The {@link YamlSemanticTag} is a data transfer object used to serialize a semantic tag diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTagProvider.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTagProvider.java index 5f79737ee11..6af680474a6 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTagProvider.java +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTagProvider.java @@ -19,13 +19,13 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.core.common.registry.AbstractProvider; +import org.openhab.core.model.core.yaml.YamlElement; +import org.openhab.core.model.core.yaml.YamlFile; +import org.openhab.core.model.core.yaml.YamlModelListener; import org.openhab.core.semantics.SemanticTag; import org.openhab.core.semantics.SemanticTagImpl; import org.openhab.core.semantics.SemanticTagProvider; import org.openhab.core.semantics.SemanticTagRegistry; -import org.openhab.core.semantics.model.yaml.YamlElement; -import org.openhab.core.semantics.model.yaml.YamlFile; -import org.openhab.core.semantics.model.yaml.YamlModelListener; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Deactivate; diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTags.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTags.java index 3f44af0c5ca..e5af9ad6905 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTags.java +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTags.java @@ -15,9 +15,9 @@ import java.util.List; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.core.semantics.model.yaml.YamlElement; -import org.openhab.core.semantics.model.yaml.YamlFile; -import org.openhab.core.semantics.model.yaml.YamlParseException; +import org.openhab.core.model.core.yaml.YamlElement; +import org.openhab.core.model.core.yaml.YamlFile; +import org.openhab.core.model.core.yaml.YamlParseException; /** * The {@link YamlSemanticTags} is a data transfer object used to serialize a list of semantic tags diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelListener.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelListener.java deleted file mode 100644 index 6a49659b659..00000000000 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelListener.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * 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.core.semantics.model.yaml; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; - -/** - * The {@link YamlModelListener} interface is responsible for managing a particular model - * with data processed from YAML configuration files. - * - * @author Laurent Garnier - Initial contribution - */ -@NonNullByDefault -public interface YamlModelListener { - - void addedModel(String modelName, List elements); - - void updatedModel(String modelName, List elements); - - void removedModel(String modelName, List elements); - - String getRootName(); - - Class getFileClass(); - - Class getElementClass(); -} From f0f67f1bf2f28373b6a0119e2003882de808904a Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sun, 9 Jul 2023 14:16:23 +0200 Subject: [PATCH 06/17] Try to fix karaf feature Signed-off-by: Laurent Garnier --- features/karaf/openhab-core/src/main/feature/feature.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/features/karaf/openhab-core/src/main/feature/feature.xml b/features/karaf/openhab-core/src/main/feature/feature.xml index ba8ed3ae829..49fd0853b2b 100644 --- a/features/karaf/openhab-core/src/main/feature/feature.xml +++ b/features/karaf/openhab-core/src/main/feature/feature.xml @@ -40,6 +40,9 @@ openhab.tp;filter:="(feature=jna)" openhab.tp-jna + openhab.tp;filter:="(feature=jackson)" + openhab.tp-jackson + mvn:org.openhab.core.bundles/org.openhab.core.automation/${project.version} mvn:org.openhab.core.bundles/org.openhab.core.config.core/${project.version} mvn:org.openhab.core.bundles/org.openhab.core.config.discovery/${project.version} @@ -53,9 +56,9 @@ mvn:org.openhab.core.bundles/org.openhab.core.ephemeris/${project.version} mvn:org.openhab.core.bundles/org.openhab.core.id/${project.version} mvn:org.openhab.core.bundles/org.openhab.core.persistence/${project.version} + mvn:org.openhab.core.bundles/org.openhab.core.model.core/${project.version} mvn:org.openhab.core.bundles/org.openhab.core.semantics/${project.version} openhab.tp-asm - openhab.tp-jackson mvn:org.openhab.core.bundles/org.openhab.core.thing/${project.version} mvn:org.openhab.core.bundles/org.openhab.core.transform/${project.version} mvn:org.openhab.core.bundles/org.openhab.core.audio/${project.version} @@ -253,6 +256,8 @@ openhab-core-base mvn:org.openhab.core.bundles/org.openhab.core.model.core/${project.version} + openhab.tp;filter:="(feature=jackson)" + openhab.tp-jackson From ee7b4e003f198e3002ec49756f7d5c566840bba0 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sun, 9 Jul 2023 15:28:51 +0200 Subject: [PATCH 07/17] Undo separation in two bundles Signed-off-by: Laurent Garnier --- bundles/org.openhab.core.semantics/pom.xml | 5 ----- .../internal/model}/yaml/YamlModelRepository.java | 10 +++++----- .../yaml => model/yaml/tags}/YamlSemanticTag.java | 6 +++--- .../yaml/tags}/YamlSemanticTagProvider.java | 8 ++++---- .../yaml => model/yaml/tags}/YamlSemanticTags.java | 8 ++++---- .../core/semantics/model}/yaml/YamlElement.java | 2 +- .../openhab/core/semantics/model}/yaml/YamlFile.java | 2 +- .../core/semantics/model}/yaml/YamlModelListener.java | 2 +- .../core/semantics/model}/yaml/YamlParseException.java | 2 +- .../karaf/openhab-core/src/main/feature/feature.xml | 3 --- 10 files changed, 20 insertions(+), 28 deletions(-) rename bundles/{org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/internal => org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model}/yaml/YamlModelRepository.java (96%) rename bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/{config/yaml => model/yaml/tags}/YamlSemanticTag.java (89%) rename bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/{config/yaml => model/yaml/tags}/YamlSemanticTagProvider.java (95%) rename bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/{config/yaml => model/yaml/tags}/YamlSemanticTags.java (81%) rename bundles/{org.openhab.core.model.core/src/main/java/org/openhab/core/model/core => org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model}/yaml/YamlElement.java (95%) rename bundles/{org.openhab.core.model.core/src/main/java/org/openhab/core/model/core => org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model}/yaml/YamlFile.java (97%) rename bundles/{org.openhab.core.model.core/src/main/java/org/openhab/core/model/core => org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model}/yaml/YamlModelListener.java (97%) rename bundles/{org.openhab.core.model.core/src/main/java/org/openhab/core/model/core => org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model}/yaml/YamlParseException.java (95%) diff --git a/bundles/org.openhab.core.semantics/pom.xml b/bundles/org.openhab.core.semantics/pom.xml index 809e0a3afe4..1ebf3cec206 100644 --- a/bundles/org.openhab.core.semantics/pom.xml +++ b/bundles/org.openhab.core.semantics/pom.xml @@ -20,11 +20,6 @@ org.openhab.core ${project.version} - - org.openhab.core.bundles - org.openhab.core.model.core - ${project.version} - org.ow2.asm asm diff --git a/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/internal/yaml/YamlModelRepository.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/YamlModelRepository.java similarity index 96% rename from bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/internal/yaml/YamlModelRepository.java rename to bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/YamlModelRepository.java index 74abfd8e33c..469f736f29d 100644 --- a/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/internal/yaml/YamlModelRepository.java +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/YamlModelRepository.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.model.core.internal.yaml; +package org.openhab.core.semantics.internal.model.yaml; import java.io.IOException; import java.nio.file.Files; @@ -24,10 +24,10 @@ import java.util.stream.Stream; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.core.model.core.yaml.YamlElement; -import org.openhab.core.model.core.yaml.YamlFile; -import org.openhab.core.model.core.yaml.YamlModelListener; -import org.openhab.core.model.core.yaml.YamlParseException; +import org.openhab.core.semantics.model.yaml.YamlElement; +import org.openhab.core.semantics.model.yaml.YamlFile; +import org.openhab.core.semantics.model.yaml.YamlModelListener; +import org.openhab.core.semantics.model.yaml.YamlParseException; import org.openhab.core.service.WatchService; import org.openhab.core.service.WatchService.Kind; import org.osgi.service.component.annotations.Activate; diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTag.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTag.java similarity index 89% rename from bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTag.java rename to bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTag.java index e4da6e02494..29f988f8147 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTag.java +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTag.java @@ -10,14 +10,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.semantics.internal.config.yaml; +package org.openhab.core.semantics.internal.model.yaml.tags; import java.util.List; import java.util.Objects; import org.eclipse.jdt.annotation.Nullable; -import org.openhab.core.model.core.yaml.YamlElement; -import org.openhab.core.model.core.yaml.YamlParseException; +import org.openhab.core.semantics.model.yaml.YamlElement; +import org.openhab.core.semantics.model.yaml.YamlParseException; /** * The {@link YamlSemanticTag} is a data transfer object used to serialize a semantic tag diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTagProvider.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTagProvider.java similarity index 95% rename from bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTagProvider.java rename to bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTagProvider.java index 6af680474a6..7be9996eaf2 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTagProvider.java +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTagProvider.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.semantics.internal.config.yaml; +package org.openhab.core.semantics.internal.model.yaml.tags; import java.util.ArrayList; import java.util.Collection; @@ -19,13 +19,13 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.core.common.registry.AbstractProvider; -import org.openhab.core.model.core.yaml.YamlElement; -import org.openhab.core.model.core.yaml.YamlFile; -import org.openhab.core.model.core.yaml.YamlModelListener; import org.openhab.core.semantics.SemanticTag; import org.openhab.core.semantics.SemanticTagImpl; import org.openhab.core.semantics.SemanticTagProvider; import org.openhab.core.semantics.SemanticTagRegistry; +import org.openhab.core.semantics.model.yaml.YamlElement; +import org.openhab.core.semantics.model.yaml.YamlFile; +import org.openhab.core.semantics.model.yaml.YamlModelListener; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Deactivate; diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTags.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTags.java similarity index 81% rename from bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTags.java rename to bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTags.java index e5af9ad6905..91676d7c07f 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/config/yaml/YamlSemanticTags.java +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTags.java @@ -10,14 +10,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.semantics.internal.config.yaml; +package org.openhab.core.semantics.internal.model.yaml.tags; import java.util.List; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.core.model.core.yaml.YamlElement; -import org.openhab.core.model.core.yaml.YamlFile; -import org.openhab.core.model.core.yaml.YamlParseException; +import org.openhab.core.semantics.model.yaml.YamlElement; +import org.openhab.core.semantics.model.yaml.YamlFile; +import org.openhab.core.semantics.model.yaml.YamlParseException; /** * The {@link YamlSemanticTags} is a data transfer object used to serialize a list of semantic tags diff --git a/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlElement.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlElement.java similarity index 95% rename from bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlElement.java rename to bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlElement.java index 209e8605ce1..5498f1aaf82 100644 --- a/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlElement.java +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlElement.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.model.core.yaml; +package org.openhab.core.semantics.model.yaml; /** * The {@link YamlElement} interface offers an identifier and a check validity method diff --git a/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlFile.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlFile.java similarity index 97% rename from bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlFile.java rename to bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlFile.java index 29ee7720867..ba52455f39d 100644 --- a/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlFile.java +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlFile.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.model.core.yaml; +package org.openhab.core.semantics.model.yaml; import java.util.List; diff --git a/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlModelListener.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelListener.java similarity index 97% rename from bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlModelListener.java rename to bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelListener.java index 148dac434a4..20d52f7c8ed 100644 --- a/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlModelListener.java +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelListener.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.model.core.yaml; +package org.openhab.core.semantics.model.yaml; import java.util.List; diff --git a/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlParseException.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlParseException.java similarity index 95% rename from bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlParseException.java rename to bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlParseException.java index 2adf8f9fe22..95894fdcc2f 100644 --- a/bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/yaml/YamlParseException.java +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlParseException.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.model.core.yaml; +package org.openhab.core.semantics.model.yaml; import org.eclipse.jdt.annotation.NonNullByDefault; diff --git a/features/karaf/openhab-core/src/main/feature/feature.xml b/features/karaf/openhab-core/src/main/feature/feature.xml index 49fd0853b2b..2ce6e19b7b8 100644 --- a/features/karaf/openhab-core/src/main/feature/feature.xml +++ b/features/karaf/openhab-core/src/main/feature/feature.xml @@ -56,7 +56,6 @@ mvn:org.openhab.core.bundles/org.openhab.core.ephemeris/${project.version} mvn:org.openhab.core.bundles/org.openhab.core.id/${project.version} mvn:org.openhab.core.bundles/org.openhab.core.persistence/${project.version} - mvn:org.openhab.core.bundles/org.openhab.core.model.core/${project.version} mvn:org.openhab.core.bundles/org.openhab.core.semantics/${project.version} openhab.tp-asm mvn:org.openhab.core.bundles/org.openhab.core.thing/${project.version} @@ -256,8 +255,6 @@ openhab-core-base mvn:org.openhab.core.bundles/org.openhab.core.model.core/${project.version} - openhab.tp;filter:="(feature=jackson)" - openhab.tp-jackson From c6856dbb1b7c5cc8b51426ad9ead01ed5e9eb096 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sun, 9 Jul 2023 16:37:02 +0200 Subject: [PATCH 08/17] Move everything in a new bundle Signed-off-by: Laurent Garnier --- bom/openhab-core/pom.xml | 6 ++++ .../org.openhab.core.model.yaml/.classpath | 29 +++++++++++++++++++ bundles/org.openhab.core.model.yaml/.project | 23 +++++++++++++++ bundles/org.openhab.core.model.yaml/NOTICE | 14 +++++++++ bundles/org.openhab.core.model.yaml/pom.xml | 29 +++++++++++++++++++ .../openhab/core}/model/yaml/YamlElement.java | 2 +- .../openhab/core}/model/yaml/YamlFile.java | 2 +- .../core}/model/yaml/YamlModelListener.java | 2 +- .../core}/model/yaml/YamlParseException.java | 2 +- .../yaml/internal}/YamlModelRepository.java | 10 +++---- .../internal/semantics}/YamlSemanticTag.java | 6 ++-- .../semantics}/YamlSemanticTagProvider.java | 8 ++--- .../internal/semantics}/YamlSemanticTags.java | 8 ++--- bundles/pom.xml | 1 + .../openhab-core/src/main/feature/feature.xml | 11 +++++-- .../itest.bndrun | 1 - .../itest.bndrun | 1 - .../itest.bndrun | 1 - .../itest.bndrun | 1 - .../itest.bndrun | 1 - 20 files changed, 130 insertions(+), 28 deletions(-) create mode 100644 bundles/org.openhab.core.model.yaml/.classpath create mode 100644 bundles/org.openhab.core.model.yaml/.project create mode 100644 bundles/org.openhab.core.model.yaml/NOTICE create mode 100644 bundles/org.openhab.core.model.yaml/pom.xml rename bundles/{org.openhab.core.semantics/src/main/java/org/openhab/core/semantics => org.openhab.core.model.yaml/src/main/java/org/openhab/core}/model/yaml/YamlElement.java (95%) rename bundles/{org.openhab.core.semantics/src/main/java/org/openhab/core/semantics => org.openhab.core.model.yaml/src/main/java/org/openhab/core}/model/yaml/YamlFile.java (97%) rename bundles/{org.openhab.core.semantics/src/main/java/org/openhab/core/semantics => org.openhab.core.model.yaml/src/main/java/org/openhab/core}/model/yaml/YamlModelListener.java (97%) rename bundles/{org.openhab.core.semantics/src/main/java/org/openhab/core/semantics => org.openhab.core.model.yaml/src/main/java/org/openhab/core}/model/yaml/YamlParseException.java (95%) rename bundles/{org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml => org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal}/YamlModelRepository.java (96%) rename bundles/{org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags => org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics}/YamlSemanticTag.java (89%) rename bundles/{org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags => org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics}/YamlSemanticTagProvider.java (95%) rename bundles/{org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags => org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics}/YamlSemanticTags.java (81%) diff --git a/bom/openhab-core/pom.xml b/bom/openhab-core/pom.xml index 1bea7c150d4..37521796c4b 100644 --- a/bom/openhab-core/pom.xml +++ b/bom/openhab-core/pom.xml @@ -496,6 +496,12 @@ ${project.version} compile + + org.openhab.core.bundles + org.openhab.core.model.yaml + ${project.version} + compile + org.openhab.core.bundles org.openhab.core.ui diff --git a/bundles/org.openhab.core.model.yaml/.classpath b/bundles/org.openhab.core.model.yaml/.classpath new file mode 100644 index 00000000000..58cd399d639 --- /dev/null +++ b/bundles/org.openhab.core.model.yaml/.classpath @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.openhab.core.model.yaml/.project b/bundles/org.openhab.core.model.yaml/.project new file mode 100644 index 00000000000..1b130d3a787 --- /dev/null +++ b/bundles/org.openhab.core.model.yaml/.project @@ -0,0 +1,23 @@ + + + org.openhab.core.model.yaml + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/bundles/org.openhab.core.model.yaml/NOTICE b/bundles/org.openhab.core.model.yaml/NOTICE new file mode 100644 index 00000000000..19bf5f2cfa8 --- /dev/null +++ b/bundles/org.openhab.core.model.yaml/NOTICE @@ -0,0 +1,14 @@ +This content is produced and maintained by the openHAB project. + +* Project home: https://www.openhab.org + +== Declared Project Licenses + +This program and the accompanying materials are made available under the terms +of the Eclipse Public License 2.0 which is available at +https://www.eclipse.org/legal/epl-2.0/. + +== Source Code + +https://github.com/openhab/openhab-core + diff --git a/bundles/org.openhab.core.model.yaml/pom.xml b/bundles/org.openhab.core.model.yaml/pom.xml new file mode 100644 index 00000000000..cfa8c9338b8 --- /dev/null +++ b/bundles/org.openhab.core.model.yaml/pom.xml @@ -0,0 +1,29 @@ + + + + 4.0.0 + + + org.openhab.core.bundles + org.openhab.core.reactor.bundles + 4.0.0-SNAPSHOT + + + org.openhab.core.model.yaml + + openHAB Core :: Bundles :: Model YAML + + + + org.openhab.core.bundles + org.openhab.core + ${project.version} + + + org.openhab.core.bundles + org.openhab.core.semantics + ${project.version} + + + diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlElement.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlElement.java similarity index 95% rename from bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlElement.java rename to bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlElement.java index 5498f1aaf82..cc1a1168fc6 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlElement.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlElement.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.semantics.model.yaml; +package org.openhab.core.model.yaml; /** * The {@link YamlElement} interface offers an identifier and a check validity method diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlFile.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlFile.java similarity index 97% rename from bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlFile.java rename to bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlFile.java index ba52455f39d..d6215a3fd62 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlFile.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlFile.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.semantics.model.yaml; +package org.openhab.core.model.yaml; import java.util.List; diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelListener.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlModelListener.java similarity index 97% rename from bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelListener.java rename to bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlModelListener.java index 20d52f7c8ed..f03bd815f34 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlModelListener.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlModelListener.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.semantics.model.yaml; +package org.openhab.core.model.yaml; import java.util.List; diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlParseException.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlParseException.java similarity index 95% rename from bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlParseException.java rename to bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlParseException.java index 95894fdcc2f..bae53ba78d9 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/model/yaml/YamlParseException.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlParseException.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.semantics.model.yaml; +package org.openhab.core.model.yaml; import org.eclipse.jdt.annotation.NonNullByDefault; diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/YamlModelRepository.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/YamlModelRepository.java similarity index 96% rename from bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/YamlModelRepository.java rename to bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/YamlModelRepository.java index 469f736f29d..8f5affb31df 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/YamlModelRepository.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/YamlModelRepository.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.semantics.internal.model.yaml; +package org.openhab.core.model.yaml.internal; import java.io.IOException; import java.nio.file.Files; @@ -24,10 +24,10 @@ import java.util.stream.Stream; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.core.semantics.model.yaml.YamlElement; -import org.openhab.core.semantics.model.yaml.YamlFile; -import org.openhab.core.semantics.model.yaml.YamlModelListener; -import org.openhab.core.semantics.model.yaml.YamlParseException; +import org.openhab.core.model.yaml.YamlElement; +import org.openhab.core.model.yaml.YamlFile; +import org.openhab.core.model.yaml.YamlModelListener; +import org.openhab.core.model.yaml.YamlParseException; import org.openhab.core.service.WatchService; import org.openhab.core.service.WatchService.Kind; import org.osgi.service.component.annotations.Activate; diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTag.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTag.java similarity index 89% rename from bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTag.java rename to bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTag.java index 29f988f8147..b50300a72ce 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTag.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTag.java @@ -10,14 +10,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.semantics.internal.model.yaml.tags; +package org.openhab.core.model.yaml.internal.semantics; import java.util.List; import java.util.Objects; import org.eclipse.jdt.annotation.Nullable; -import org.openhab.core.semantics.model.yaml.YamlElement; -import org.openhab.core.semantics.model.yaml.YamlParseException; +import org.openhab.core.model.yaml.YamlElement; +import org.openhab.core.model.yaml.YamlParseException; /** * The {@link YamlSemanticTag} is a data transfer object used to serialize a semantic tag diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTagProvider.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTagProvider.java similarity index 95% rename from bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTagProvider.java rename to bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTagProvider.java index 7be9996eaf2..cc674803b01 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTagProvider.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTagProvider.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.semantics.internal.model.yaml.tags; +package org.openhab.core.model.yaml.internal.semantics; import java.util.ArrayList; import java.util.Collection; @@ -19,13 +19,13 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.core.common.registry.AbstractProvider; +import org.openhab.core.model.yaml.YamlElement; +import org.openhab.core.model.yaml.YamlFile; +import org.openhab.core.model.yaml.YamlModelListener; import org.openhab.core.semantics.SemanticTag; import org.openhab.core.semantics.SemanticTagImpl; import org.openhab.core.semantics.SemanticTagProvider; import org.openhab.core.semantics.SemanticTagRegistry; -import org.openhab.core.semantics.model.yaml.YamlElement; -import org.openhab.core.semantics.model.yaml.YamlFile; -import org.openhab.core.semantics.model.yaml.YamlModelListener; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Deactivate; diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTags.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTags.java similarity index 81% rename from bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTags.java rename to bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTags.java index 91676d7c07f..2bd0cbaf609 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/model/yaml/tags/YamlSemanticTags.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTags.java @@ -10,14 +10,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.core.semantics.internal.model.yaml.tags; +package org.openhab.core.model.yaml.internal.semantics; import java.util.List; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.core.semantics.model.yaml.YamlElement; -import org.openhab.core.semantics.model.yaml.YamlFile; -import org.openhab.core.semantics.model.yaml.YamlParseException; +import org.openhab.core.model.yaml.YamlElement; +import org.openhab.core.model.yaml.YamlFile; +import org.openhab.core.model.yaml.YamlParseException; /** * The {@link YamlSemanticTags} is a data transfer object used to serialize a list of semantic tags diff --git a/bundles/pom.xml b/bundles/pom.xml index c0fac698fad..09fb4a554e3 100644 --- a/bundles/pom.xml +++ b/bundles/pom.xml @@ -99,6 +99,7 @@ org.openhab.core.model.thing org.openhab.core.model.thing.ide org.openhab.core.model.thing.runtime + org.openhab.core.model.yaml org.openhab.core.storage.json org.openhab.core.test org.openhab.core.test.magic diff --git a/features/karaf/openhab-core/src/main/feature/feature.xml b/features/karaf/openhab-core/src/main/feature/feature.xml index 2ce6e19b7b8..55135194294 100644 --- a/features/karaf/openhab-core/src/main/feature/feature.xml +++ b/features/karaf/openhab-core/src/main/feature/feature.xml @@ -40,9 +40,6 @@ openhab.tp;filter:="(feature=jna)" openhab.tp-jna - openhab.tp;filter:="(feature=jackson)" - openhab.tp-jackson - mvn:org.openhab.core.bundles/org.openhab.core.automation/${project.version} mvn:org.openhab.core.bundles/org.openhab.core.config.core/${project.version} mvn:org.openhab.core.bundles/org.openhab.core.config.discovery/${project.version} @@ -373,6 +370,13 @@ mvn:org.openhab.core.bundles/org.openhab.core.model.lsp/${project.version} + + openhab-core-base + mvn:org.openhab.core.bundles/org.openhab.core.model.yaml/${project.version} + openhab.tp;filter:="(feature=jackson)" + openhab.tp-jackson + + openhab-core-base @@ -417,6 +421,7 @@ openhab-core-model-script openhab-core-model-sitemap openhab-core-model-thing + openhab-core-model-yaml openhab-core-ui-icon openhab-core-storage-json openhab-runtime-certificate diff --git a/itests/org.openhab.core.io.rest.core.tests/itest.bndrun b/itests/org.openhab.core.io.rest.core.tests/itest.bndrun index d839db2d30c..21cf1349327 100644 --- a/itests/org.openhab.core.io.rest.core.tests/itest.bndrun +++ b/itests/org.openhab.core.io.rest.core.tests/itest.bndrun @@ -67,7 +67,6 @@ Fragment-Host: org.openhab.core.io.rest.core org.openhab.core.test;version='[4.0.0,4.0.1)',\ org.openhab.core.thing;version='[4.0.0,4.0.1)',\ org.openhab.core.transform;version='[4.0.0,4.0.1)',\ - com.fasterxml.jackson.dataformat;version='[2.14.1,2.14.2)',\ io.methvin.directory-watcher;version='[0.17.1,0.17.2)',\ com.sun.jna;version='[5.12.1,5.12.2)',\ com.fasterxml.woodstox.woodstox-core;version='[6.4.0,6.4.1)',\ diff --git a/itests/org.openhab.core.model.item.tests/itest.bndrun b/itests/org.openhab.core.model.item.tests/itest.bndrun index 5d533388137..19c699af908 100644 --- a/itests/org.openhab.core.model.item.tests/itest.bndrun +++ b/itests/org.openhab.core.model.item.tests/itest.bndrun @@ -79,7 +79,6 @@ Fragment-Host: org.openhab.core.model.item org.openhab.core.thing;version='[4.0.0,4.0.1)',\ org.openhab.core.transform;version='[4.0.0,4.0.1)',\ org.openhab.core.voice;version='[4.0.0,4.0.1)',\ - com.fasterxml.jackson.dataformat;version='[2.14.1,2.14.2)',\ io.methvin.directory-watcher;version='[0.17.1,0.17.2)',\ com.sun.jna;version='[5.12.1,5.12.2)',\ org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ diff --git a/itests/org.openhab.core.model.rule.tests/itest.bndrun b/itests/org.openhab.core.model.rule.tests/itest.bndrun index ad82cb21066..0956d07ece1 100644 --- a/itests/org.openhab.core.model.rule.tests/itest.bndrun +++ b/itests/org.openhab.core.model.rule.tests/itest.bndrun @@ -83,7 +83,6 @@ Fragment-Host: org.openhab.core.model.rule.runtime org.openhab.core.thing;version='[4.0.0,4.0.1)',\ org.openhab.core.transform;version='[4.0.0,4.0.1)',\ org.openhab.core.voice;version='[4.0.0,4.0.1)',\ - com.fasterxml.jackson.dataformat;version='[2.14.1,2.14.2)',\ io.methvin.directory-watcher;version='[0.17.1,0.17.2)',\ com.sun.jna;version='[5.12.1,5.12.2)',\ org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ diff --git a/itests/org.openhab.core.model.script.tests/itest.bndrun b/itests/org.openhab.core.model.script.tests/itest.bndrun index dff6e8b4b94..b9de3468ee1 100644 --- a/itests/org.openhab.core.model.script.tests/itest.bndrun +++ b/itests/org.openhab.core.model.script.tests/itest.bndrun @@ -81,7 +81,6 @@ Fragment-Host: org.openhab.core.model.script org.openhab.core.thing;version='[4.0.0,4.0.1)',\ org.openhab.core.transform;version='[4.0.0,4.0.1)',\ org.openhab.core.voice;version='[4.0.0,4.0.1)',\ - com.fasterxml.jackson.dataformat;version='[2.14.1,2.14.2)',\ io.methvin.directory-watcher;version='[0.17.1,0.17.2)',\ com.sun.jna;version='[5.12.1,5.12.2)',\ org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ diff --git a/itests/org.openhab.core.model.thing.tests/itest.bndrun b/itests/org.openhab.core.model.thing.tests/itest.bndrun index 6921c9c262c..25c8c33ec06 100644 --- a/itests/org.openhab.core.model.thing.tests/itest.bndrun +++ b/itests/org.openhab.core.model.thing.tests/itest.bndrun @@ -82,7 +82,6 @@ Fragment-Host: org.openhab.core.model.thing org.openhab.core.thing;version='[4.0.0,4.0.1)',\ org.openhab.core.transform;version='[4.0.0,4.0.1)',\ org.openhab.core.voice;version='[4.0.0,4.0.1)',\ - com.fasterxml.jackson.dataformat;version='[2.14.1,2.14.2)',\ io.methvin.directory-watcher;version='[0.17.1,0.17.2)',\ com.sun.jna;version='[5.12.1,5.12.2)',\ org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\ From 8744b8f03d1971f3d9e3301f2b92b0414d105230 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Thu, 7 Dec 2023 00:58:41 +0100 Subject: [PATCH 09/17] Fix version in POM after rebasing to OH 4.1 Signed-off-by: Laurent Garnier --- bundles/org.openhab.core.model.yaml/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.core.model.yaml/pom.xml b/bundles/org.openhab.core.model.yaml/pom.xml index cfa8c9338b8..00941ec4b21 100644 --- a/bundles/org.openhab.core.model.yaml/pom.xml +++ b/bundles/org.openhab.core.model.yaml/pom.xml @@ -7,7 +7,7 @@ org.openhab.core.bundles org.openhab.core.reactor.bundles - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT org.openhab.core.model.yaml From 894e876c032b89ce6d3728d8953edf25c9e8abc6 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Thu, 7 Dec 2023 01:52:59 +0100 Subject: [PATCH 10/17] Consider review comments about checkVersion and checkValidity Signed-off-by: Laurent Garnier --- .../openhab/core/model/yaml/YamlElement.java | 4 +-- .../org/openhab/core/model/yaml/YamlFile.java | 33 ++++++++++--------- .../yaml/internal/YamlModelRepository.java | 4 ++- .../internal/semantics/YamlSemanticTag.java | 11 +++++-- .../internal/semantics/YamlSemanticTags.java | 8 ----- 5 files changed, 31 insertions(+), 29 deletions(-) diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlElement.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlElement.java index cc1a1168fc6..957fad06233 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlElement.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlElement.java @@ -30,7 +30,7 @@ public interface YamlElement { /** * Check that the YAML element is valid * - * @throws YamlParseException if something is wrong + * @return true if all the checks are OK */ - void checkValidity() throws YamlParseException; + boolean isValid(); } diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlFile.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlFile.java index d6215a3fd62..3da650487ee 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlFile.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlFile.java @@ -15,6 +15,8 @@ import java.util.List; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The {@link YamlFile} is the DTO base class used to map a YAML configuration file. @@ -26,6 +28,8 @@ @NonNullByDefault public abstract class YamlFile { + private final Logger logger = LoggerFactory.getLogger(YamlFile.class); + /** * YAML file version */ @@ -39,37 +43,36 @@ public abstract class YamlFile { public abstract List getElements(); /** - * Check that the version in the YAML file in the expected one. + * Get the version present in the YAML file. * - * @throws YamlParseException if the version in the file is not the expected one + * @return the version in the file */ - protected abstract void checkVersion() throws YamlParseException; + public int getVersion() { + return version; + } /** * Check that the file content is valid. - * It includes the check of the version, the check of duplicated elements (same identifier) - * and the check of each element. + * It includes the check of duplicated elements (same identifier) and the check of each element. * - * @throws YamlParseException if something is invalid + * @return true if all the checks are OK */ - public void checkValidity() throws YamlParseException { - // Checking version - checkVersion(); - + public boolean isValid() { // Checking duplicated elements List elts = getElements(); long nbDistinctIds = elts.stream().map(YamlElement::getId).distinct().count(); if (nbDistinctIds < elts.size()) { - throw new YamlParseException("Elements with same ids detected in the file"); + logger.debug("Elements with same ids detected in the file"); + return false; } // Checking each element for (int i = 0; i < elts.size(); i++) { - try { - elts.get(i).checkValidity(); - } catch (YamlParseException e) { - throw new YamlParseException("Error in element " + (i + 1) + ": " + e.getMessage()); + if (!elts.get(i).isValid()) { + logger.debug("Error in element {}", i + 1); + return false; } } + return true; } } diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/YamlModelRepository.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/YamlModelRepository.java index 8f5affb31df..9d949e46f6e 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/YamlModelRepository.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/YamlModelRepository.java @@ -159,7 +159,9 @@ private YamlFile readYamlFile(Path path, Class dtoClass) thr logger.debug("readYamlFile {} with {}", path.toFile().getAbsolutePath(), dtoClass.getName()); try { YamlFile dto = yamlReader.readValue(path.toFile(), dtoClass); - dto.checkValidity(); + if (!dto.isValid()) { + throw new YamlParseException("The file is not valid, some checks failed!"); + } return dto; } catch (IOException e) { throw new YamlParseException(e); diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTag.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTag.java index b50300a72ce..9d8f0865abd 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTag.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTag.java @@ -17,7 +17,8 @@ import org.eclipse.jdt.annotation.Nullable; import org.openhab.core.model.yaml.YamlElement; -import org.openhab.core.model.yaml.YamlParseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The {@link YamlSemanticTag} is a data transfer object used to serialize a semantic tag @@ -27,6 +28,8 @@ */ public class YamlSemanticTag implements YamlElement { + private final Logger logger = LoggerFactory.getLogger(YamlSemanticTag.class); + public String uid; public String label; public String description; @@ -41,10 +44,12 @@ public String getId() { } @Override - public void checkValidity() throws YamlParseException { + public boolean isValid() { if (uid == null) { - throw new YamlParseException("uid missing"); + logger.debug("uid missing"); + return false; } + return true; } @Override diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTags.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTags.java index 2bd0cbaf609..f4431603120 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTags.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTags.java @@ -17,7 +17,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.core.model.yaml.YamlElement; import org.openhab.core.model.yaml.YamlFile; -import org.openhab.core.model.yaml.YamlParseException; /** * The {@link YamlSemanticTags} is a data transfer object used to serialize a list of semantic tags @@ -34,11 +33,4 @@ public class YamlSemanticTags extends YamlFile { public List getElements() { return tags; } - - @Override - protected void checkVersion() throws YamlParseException { - if (version != 1) { - throw new YamlParseException("Version 1 required; please convert your file"); - } - } } From 5c9c0f2af9fdfbbd54eeae832278a5e407ad6ba0 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sat, 9 Dec 2023 10:34:19 +0100 Subject: [PATCH 11/17] Review comments: log level and variable name Signed-off-by: Laurent Garnier --- .../yaml/internal/YamlModelRepository.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/YamlModelRepository.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/YamlModelRepository.java index 9d949e46f6e..47af128ffc6 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/YamlModelRepository.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/YamlModelRepository.java @@ -84,7 +84,7 @@ public synchronized void processWatchEvent(Kind kind, Path path) { String dirName = path.subpath(0, 1).toString(); if (Files.isDirectory(fullPath) || fullPath.toFile().isHidden() || !fullPath.toString().endsWith(".yaml")) { - logger.debug("Ignored {}", fullPath); + logger.trace("Ignored {}", fullPath); return; } @@ -127,31 +127,31 @@ private void processWatchEvent(String dirName, Kind kind, Path fullPath, YamlMod String modelName = fullPath.toFile().getName(); modelName = modelName.substring(0, modelName.indexOf(".yaml")); - List listElts; - listElts = oldObjects.entrySet().stream() + List listElements; + listElements = oldObjects.entrySet().stream() .filter(entry -> entry.getValue().getClass().equals(listener.getElementClass()) && !newObjects.containsKey(entry.getKey())) .map(Map.Entry::getValue).toList(); - if (!listElts.isEmpty()) { - listener.removedModel(modelName, listElts); + if (!listElements.isEmpty()) { + listener.removedModel(modelName, listElements); } - listElts = newObjects.entrySet().stream() + listElements = newObjects.entrySet().stream() .filter(entry -> entry.getValue().getClass().equals(listener.getElementClass()) && !oldObjects.containsKey(entry.getKey())) .map(Map.Entry::getValue).toList(); - if (!listElts.isEmpty()) { - listener.addedModel(modelName, listElts); + if (!listElements.isEmpty()) { + listener.addedModel(modelName, listElements); } // Object is ignored if unchanged - listElts = newObjects.entrySet().stream() + listElements = newObjects.entrySet().stream() .filter(entry -> entry.getValue().getClass().equals(listener.getElementClass()) && oldObjects.containsKey(entry.getKey()) && !entry.getValue().equals(oldObjects.get(entry.getKey()))) .map(Map.Entry::getValue).toList(); - if (!listElts.isEmpty()) { - listener.updatedModel(modelName, listElts); + if (!listElements.isEmpty()) { + listener.updatedModel(modelName, listElements); } } From e7f0281e3506100edaecbc8b82fa8b7f0642a11c Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sat, 9 Dec 2023 11:21:41 +0100 Subject: [PATCH 12/17] Review comment: convert YamlFile in interface and add an abstract class Signed-off-by: Laurent Garnier --- .../core/model/yaml/AbstractYamlFile.java | 65 +++++++++++++++++++ .../org/openhab/core/model/yaml/YamlFile.java | 40 ++---------- .../core/model/yaml/YamlModelListener.java | 2 +- .../yaml/internal/YamlModelRepository.java | 9 +-- .../semantics/YamlSemanticTagProvider.java | 4 +- .../internal/semantics/YamlSemanticTags.java | 4 +- 6 files changed, 80 insertions(+), 44 deletions(-) create mode 100644 bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/AbstractYamlFile.java diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/AbstractYamlFile.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/AbstractYamlFile.java new file mode 100644 index 00000000000..d99c8151ca1 --- /dev/null +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/AbstractYamlFile.java @@ -0,0 +1,65 @@ +/** + * 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.core.model.yaml; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link AbstractYamlFile} is the DTO base class used to map a YAML configuration file. + * + * A YAML configuration file consists of a version and a list of elements. + * + * @author Laurent Garnier - Initial contribution + */ +@NonNullByDefault +public abstract class AbstractYamlFile implements YamlFile { + + private final Logger logger = LoggerFactory.getLogger(AbstractYamlFile.class); + + /** + * YAML file version + */ + public int version; + + @Override + public abstract List getElements(); + + @Override + public int getVersion() { + return version; + } + + @Override + public boolean isValid() { + // Checking duplicated elements + List elts = getElements(); + long nbDistinctIds = elts.stream().map(YamlElement::getId).distinct().count(); + if (nbDistinctIds < elts.size()) { + logger.debug("Elements with same ids detected in the file"); + return false; + } + + // Checking each element + for (int i = 0; i < elts.size(); i++) { + if (!elts.get(i).isValid()) { + logger.debug("Error in element {}", i + 1); + return false; + } + } + return true; + } +} diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlFile.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlFile.java index 3da650487ee..40f5ce4c9c8 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlFile.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlFile.java @@ -15,41 +15,28 @@ import java.util.List; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * The {@link YamlFile} is the DTO base class used to map a YAML configuration file. - * - * A YAML configuration file consists of a version and a list of elements. + * The {@link YamlFile} is the interface to manage the generic content of a YAML configuration file. * * @author Laurent Garnier - Initial contribution */ @NonNullByDefault -public abstract class YamlFile { - - private final Logger logger = LoggerFactory.getLogger(YamlFile.class); - - /** - * YAML file version - */ - public int version; +public interface YamlFile { /** * Get the list of elements present in the YAML file. * * @return the list of elements */ - public abstract List getElements(); + List getElements(); /** * Get the version present in the YAML file. * * @return the version in the file */ - public int getVersion() { - return version; - } + int getVersion(); /** * Check that the file content is valid. @@ -57,22 +44,5 @@ public int getVersion() { * * @return true if all the checks are OK */ - public boolean isValid() { - // Checking duplicated elements - List elts = getElements(); - long nbDistinctIds = elts.stream().map(YamlElement::getId).distinct().count(); - if (nbDistinctIds < elts.size()) { - logger.debug("Elements with same ids detected in the file"); - return false; - } - - // Checking each element - for (int i = 0; i < elts.size(); i++) { - if (!elts.get(i).isValid()) { - logger.debug("Error in element {}", i + 1); - return false; - } - } - return true; - } + boolean isValid(); } diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlModelListener.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlModelListener.java index f03bd815f34..ec6772510e3 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlModelListener.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlModelListener.java @@ -64,7 +64,7 @@ public interface YamlModelListener { * * @return the DTO file class */ - Class getFileClass(); + Class getFileClass(); /** * Get the DTO class to be used for each object of this model type. diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/YamlModelRepository.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/YamlModelRepository.java index 47af128ffc6..a7d04138762 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/YamlModelRepository.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/YamlModelRepository.java @@ -24,8 +24,8 @@ import java.util.stream.Stream; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.model.yaml.AbstractYamlFile; import org.openhab.core.model.yaml.YamlElement; -import org.openhab.core.model.yaml.YamlFile; import org.openhab.core.model.yaml.YamlModelListener; import org.openhab.core.model.yaml.YamlParseException; import org.openhab.core.service.WatchService; @@ -105,7 +105,7 @@ private void processWatchEvent(String dirName, Kind kind, Path fullPath, YamlMod } oldObjects = oldListObjects.stream().collect(Collectors.toMap(YamlElement::getId, obj -> obj)); } else { - YamlFile yamlData; + AbstractYamlFile yamlData; try { yamlData = readYamlFile(fullPath, listener.getFileClass()); } catch (YamlParseException e) { @@ -155,10 +155,11 @@ private void processWatchEvent(String dirName, Kind kind, Path fullPath, YamlMod } } - private YamlFile readYamlFile(Path path, Class dtoClass) throws YamlParseException { + private AbstractYamlFile readYamlFile(Path path, Class dtoClass) + throws YamlParseException { logger.debug("readYamlFile {} with {}", path.toFile().getAbsolutePath(), dtoClass.getName()); try { - YamlFile dto = yamlReader.readValue(path.toFile(), dtoClass); + AbstractYamlFile dto = yamlReader.readValue(path.toFile(), dtoClass); if (!dto.isValid()) { throw new YamlParseException("The file is not valid, some checks failed!"); } diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTagProvider.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTagProvider.java index cc674803b01..dca85dfa061 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTagProvider.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTagProvider.java @@ -19,8 +19,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.core.common.registry.AbstractProvider; +import org.openhab.core.model.yaml.AbstractYamlFile; import org.openhab.core.model.yaml.YamlElement; -import org.openhab.core.model.yaml.YamlFile; import org.openhab.core.model.yaml.YamlModelListener; import org.openhab.core.semantics.SemanticTag; import org.openhab.core.semantics.SemanticTagImpl; @@ -70,7 +70,7 @@ public String getRootName() { } @Override - public Class getFileClass() { + public Class getFileClass() { return YamlSemanticTags.class; } diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTags.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTags.java index f4431603120..3c2a4ee9609 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTags.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTags.java @@ -15,8 +15,8 @@ import java.util.List; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.model.yaml.AbstractYamlFile; import org.openhab.core.model.yaml.YamlElement; -import org.openhab.core.model.yaml.YamlFile; /** * The {@link YamlSemanticTags} is a data transfer object used to serialize a list of semantic tags @@ -25,7 +25,7 @@ * @author Laurent Garnier - Initial contribution */ @NonNullByDefault -public class YamlSemanticTags extends YamlFile { +public class YamlSemanticTags extends AbstractYamlFile { public List tags = List.of(); From ae85687f881e8e31ee9f917a0c56a6aa774fb77e Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sat, 9 Dec 2023 11:24:38 +0100 Subject: [PATCH 13/17] Add @NonNullByDefault to YamlElement Signed-off-by: Laurent Garnier --- .../src/main/java/org/openhab/core/model/yaml/YamlElement.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlElement.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlElement.java index 957fad06233..2b1d8b16a03 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlElement.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlElement.java @@ -12,12 +12,15 @@ */ package org.openhab.core.model.yaml; +import org.eclipse.jdt.annotation.NonNullByDefault; + /** * The {@link YamlElement} interface offers an identifier and a check validity method * to any element defined in a YAML configuration file. * * @author Laurent Garnier - Initial contribution */ +@NonNullByDefault public interface YamlElement { /** From 843a1014b5d22ac08944f10c578f38eb63a303e7 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sat, 9 Dec 2023 11:55:54 +0100 Subject: [PATCH 14/17] Review comment: use Collection instead of List Signed-off-by: Laurent Garnier --- .../openhab/core/model/yaml/YamlModelListener.java | 14 +++++++------- .../semantics/YamlSemanticTagProvider.java | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlModelListener.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlModelListener.java index ec6772510e3..b15a8d9d639 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlModelListener.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/YamlModelListener.java @@ -12,7 +12,7 @@ */ package org.openhab.core.model.yaml; -import java.util.List; +import java.util.Collection; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -29,25 +29,25 @@ public interface YamlModelListener { * Method called by the model repository when elements from a model are added. * * @param modelName the name of the model - * @param elements the list of added elements + * @param elements the collection of added elements */ - void addedModel(String modelName, List elements); + void addedModel(String modelName, Collection elements); /** * Method called by the model repository when elements from a model are updated. * * @param modelName the name of the model - * @param elements the list of updated elements + * @param elements the collection of updated elements */ - void updatedModel(String modelName, List elements); + void updatedModel(String modelName, Collection elements); /** * Method called by the model repository when elements from a model are removed. * * @param modelName the name of the model - * @param elements the list of removed elements + * @param elements the collection of removed elements */ - void removedModel(String modelName, List elements); + void removedModel(String modelName, Collection elements); /** * Get the root name of this model type which is also the name of the root folder diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTagProvider.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTagProvider.java index dca85dfa061..ccda463fdd1 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTagProvider.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTagProvider.java @@ -80,7 +80,7 @@ public Class getElementClass() { } @Override - public void addedModel(String modelName, List elements) { + public void addedModel(String modelName, Collection elements) { List added = elements.stream().map(e -> mapSemanticTag((YamlSemanticTag) e)) .sorted(Comparator.comparing(SemanticTag::getUID)).toList(); tags.addAll(added); @@ -91,7 +91,7 @@ public void addedModel(String modelName, List elements) { } @Override - public void updatedModel(String modelName, List elements) { + public void updatedModel(String modelName, Collection elements) { List updated = elements.stream().map(e -> mapSemanticTag((YamlSemanticTag) e)).toList(); updated.forEach(t -> { tags.stream().filter(tag -> tag.getUID().equals(t.getUID())).findFirst().ifPresentOrElse(oldTag -> { @@ -104,7 +104,7 @@ public void updatedModel(String modelName, List elements) } @Override - public void removedModel(String modelName, List elements) { + public void removedModel(String modelName, Collection elements) { List removed = elements.stream().map(e -> mapSemanticTag((YamlSemanticTag) e)) .sorted(Comparator.comparing(SemanticTag::getUID).reversed()).toList(); removed.forEach(t -> { From 0fe0a9dd075c6341644c07615a4005347cdad230 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sat, 9 Dec 2023 12:15:09 +0100 Subject: [PATCH 15/17] Review comment: use a TreeSet instead of a Lust for tags Signed-off-by: Laurent Garnier --- .../yaml/internal/semantics/YamlSemanticTagProvider.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTagProvider.java b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTagProvider.java index ccda463fdd1..4f13120b9a1 100644 --- a/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTagProvider.java +++ b/bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/semantics/YamlSemanticTagProvider.java @@ -12,10 +12,11 @@ */ package org.openhab.core.model.yaml.internal.semantics; -import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.List; +import java.util.Set; +import java.util.TreeSet; import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.core.common.registry.AbstractProvider; @@ -48,7 +49,7 @@ public class YamlSemanticTagProvider extends AbstractProvider private final Logger logger = LoggerFactory.getLogger(YamlSemanticTagProvider.class); - private final List tags = new ArrayList<>(); + private final Set tags = new TreeSet<>(Comparator.comparing(SemanticTag::getUID)); @Activate public YamlSemanticTagProvider() { @@ -61,7 +62,7 @@ public void deactivate() { @Override public Collection getAll() { - return tags.stream().sorted(Comparator.comparing(SemanticTag::getUID)).toList(); + return tags; } @Override From dff2b22027fbb4a1de329f219e94539d77a1e88a Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sat, 9 Dec 2023 21:42:57 +0100 Subject: [PATCH 16/17] Listening of semantic tag reigstry changes added to SemanticsMetadataProvider Signed-off-by: Laurent Garnier --- .../internal/SemanticsMetadataProvider.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/SemanticsMetadataProvider.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/SemanticsMetadataProvider.java index 863594d15b8..7239e1f732b 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/SemanticsMetadataProvider.java +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/SemanticsMetadataProvider.java @@ -22,6 +22,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.core.common.registry.AbstractProvider; +import org.openhab.core.common.registry.RegistryChangeListener; import org.openhab.core.items.GroupItem; import org.openhab.core.items.Item; import org.openhab.core.items.ItemRegistry; @@ -33,6 +34,7 @@ import org.openhab.core.semantics.Location; import org.openhab.core.semantics.Point; import org.openhab.core.semantics.Property; +import org.openhab.core.semantics.SemanticTag; import org.openhab.core.semantics.SemanticTagRegistry; import org.openhab.core.semantics.SemanticTags; import org.openhab.core.semantics.Tag; @@ -72,11 +74,16 @@ public class SemanticsMetadataProvider extends AbstractProvider private final Map semantics = new TreeMap<>(String::compareTo); private final ItemRegistry itemRegistry; + private final SemanticTagRegistry semanticTagRegistry; + + private SemanticTagRegistryChangeListener listener; @Activate public SemanticsMetadataProvider(final @Reference ItemRegistry itemRegistry, final @Reference SemanticTagRegistry semanticTagRegistry) { this.itemRegistry = itemRegistry; + this.semanticTagRegistry = semanticTagRegistry; + this.listener = new SemanticTagRegistryChangeListener(this); } @Activate @@ -86,10 +93,12 @@ protected void activate() { processItem(item); } itemRegistry.addRegistryChangeListener(this); + semanticTagRegistry.addRegistryChangeListener(listener); } @Deactivate protected void deactivate() { + semanticTagRegistry.removeRegistryChangeListener(listener); itemRegistry.removeRegistryChangeListener(this); semantics.clear(); } @@ -280,4 +289,28 @@ public void removed(Item item) { public void updated(Item oldItem, Item item) { processItem(item); } + + class SemanticTagRegistryChangeListener implements RegistryChangeListener { + + private SemanticsMetadataProvider provider; + + public SemanticTagRegistryChangeListener(SemanticsMetadataProvider provider) { + this.provider = provider; + } + + @Override + public void added(SemanticTag element) { + provider.allItemsChanged(List.of()); + } + + @Override + public void removed(SemanticTag element) { + provider.allItemsChanged(List.of()); + } + + @Override + public void updated(SemanticTag oldElement, SemanticTag element) { + provider.allItemsChanged(List.of()); + } + } } From cadf8b4a0e94a58d15e8d4405607374a4de5483f Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Sun, 10 Dec 2023 10:47:57 +0100 Subject: [PATCH 17/17] Make SemanticTagRegistryChangeListener private Signed-off-by: Laurent Garnier --- .../core/semantics/internal/SemanticsMetadataProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/SemanticsMetadataProvider.java b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/SemanticsMetadataProvider.java index 7239e1f732b..93c842f06a4 100644 --- a/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/SemanticsMetadataProvider.java +++ b/bundles/org.openhab.core.semantics/src/main/java/org/openhab/core/semantics/internal/SemanticsMetadataProvider.java @@ -290,7 +290,7 @@ public void updated(Item oldItem, Item item) { processItem(item); } - class SemanticTagRegistryChangeListener implements RegistryChangeListener { + private class SemanticTagRegistryChangeListener implements RegistryChangeListener { private SemanticsMetadataProvider provider;