From a868456a3190ee06be86c335140400f29cfadc3e Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Mon, 8 Jan 2024 02:38:13 +0100 Subject: [PATCH] Stablize location and connection consistency handling --- lib/jul | 2 +- .../ConnectionLocationConsistencyHandler.java | 115 ------------------ .../ConnectionLocationConsistencyHandler.kt | 104 ++++++++++++++++ .../ConnectionTilesConsistencyHandler.java | 83 ------------- .../ConnectionTilesConsistencyHandler.kt | 42 +++++++ 5 files changed, 147 insertions(+), 199 deletions(-) delete mode 100644 module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/connectionconfig/ConnectionLocationConsistencyHandler.java create mode 100644 module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/connectionconfig/ConnectionLocationConsistencyHandler.kt delete mode 100644 module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/connectionconfig/ConnectionTilesConsistencyHandler.java create mode 100644 module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/connectionconfig/ConnectionTilesConsistencyHandler.kt diff --git a/lib/jul b/lib/jul index cf1d00daea..73c837a361 160000 --- a/lib/jul +++ b/lib/jul @@ -1 +1 @@ -Subproject commit cf1d00daead828760b101c0e670e2e70f85b286e +Subproject commit 73c837a3617e3490a87f6acc88a72e4f7099aed6 diff --git a/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/connectionconfig/ConnectionLocationConsistencyHandler.java b/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/connectionconfig/ConnectionLocationConsistencyHandler.java deleted file mode 100644 index 8621070923..0000000000 --- a/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/connectionconfig/ConnectionLocationConsistencyHandler.java +++ /dev/null @@ -1,115 +0,0 @@ -package org.openbase.bco.registry.unit.core.consistency.connectionconfig; - -/* - * #%L - * BCO Registry Unit Core - * %% - * Copyright (C) 2014 - 2021 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import org.openbase.jul.exception.CouldNotPerformException; -import org.openbase.jul.extension.protobuf.IdentifiableMessage; -import org.openbase.jul.storage.registry.AbstractProtoBufRegistryConsistencyHandler; -import org.openbase.jul.storage.registry.EntryModification; -import org.openbase.jul.storage.registry.ProtoBufFileSynchronizedRegistry; -import org.openbase.type.spatial.PlacementConfigType.PlacementConfig; -import org.openbase.jul.extension.protobuf.container.ProtoBufMessageMap; -import org.openbase.jul.storage.registry.ProtoBufRegistry; -import org.openbase.type.domotic.unit.UnitConfigType.UnitConfig; -import org.openbase.type.domotic.registry.UnitRegistryDataType.UnitRegistryData; - -/** - * - * @author Tamino Huxohl - */ -public class ConnectionLocationConsistencyHandler extends AbstractProtoBufRegistryConsistencyHandler { - - private final ProtoBufFileSynchronizedRegistry locationRegistry; - - public ConnectionLocationConsistencyHandler(ProtoBufFileSynchronizedRegistry locationRegistry) { - this.locationRegistry = locationRegistry; - } - - @Override - public void processData(String id, IdentifiableMessage entry, ProtoBufMessageMap entryMap, ProtoBufRegistry registry) throws CouldNotPerformException, EntryModification { - UnitConfig.Builder connectionUnitConfig = entry.getMessage().toBuilder(); - - String locationId; - try { - locationId = getLowestCommonParentLocation(connectionUnitConfig.getConnectionConfig().getTileIdList(), locationRegistry).getId(); - } catch (CouldNotPerformException ex) { - throw new CouldNotPerformException("Could not find parent location for connection [" + connectionUnitConfig + "]", ex); - } - if (!locationId.equals(connectionUnitConfig.getPlacementConfig().getLocationId())) { - PlacementConfig.Builder placement = connectionUnitConfig.getPlacementConfig().toBuilder().setLocationId(locationId); - throw new EntryModification(entry.setMessage(connectionUnitConfig.setPlacementConfig(placement), this), this); - } - } - - public static UnitConfig getLowestCommonParentLocation(List locationIds, ProtoBufFileSynchronizedRegistry locationUnitConfigRegistry) throws CouldNotPerformException { - // list containing the pathes from root to each location given by locationIds sorted by the lenght of the path, e.g.: - // home, apartment, hallway, entrance - // home, apartment, outdoor - final List> pathesFromRootMap = new ArrayList<>(); - - // fill the list according to the description above - for (String id : locationIds) { - UnitConfig locationUnitConfig = locationUnitConfigRegistry.getMessage(id); - final List pathFromRootList = new ArrayList<>(); - pathFromRootList.add(locationUnitConfig); - while (!locationUnitConfig.getLocationConfig().getRoot()) { - locationUnitConfig = locationUnitConfigRegistry.getMessage(locationUnitConfig.getPlacementConfig().getLocationId()); - // when adding a location at the front of the list, every entry is moved an index further - pathFromRootList.add(0, locationUnitConfig); - } - pathesFromRootMap.add(pathFromRootList); - } - - // sort the list after their sizes: - // home, apartment, outdoor - // home, apartment, hallway, entrance - pathesFromRootMap.sort(new Comparator>() { - - @Override - public int compare(List o1, List o2) { - return o2.size() - o1.size(); - } - }); - - // find the lowest common parent, e.g. for the example above apartment - // by returning the index before the first elements where the pathes differ - int shortestPath = pathesFromRootMap.get(0).size(); - for (int i = 0; i < shortestPath; ++i) { - String currentId = pathesFromRootMap.get(0).get(i).getId(); - for (int j = 1; j < pathesFromRootMap.size(); ++j) { - if (!pathesFromRootMap.get(j).get(i).getId().equals(currentId)) { - return pathesFromRootMap.get(0).get(i - 1); - } - } - } - - // checking if a lowst common parent exists should not be necessary since a tile cannot be root - return pathesFromRootMap.get(0).get(0); - } - - @Override - public void reset() { - } -} diff --git a/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/connectionconfig/ConnectionLocationConsistencyHandler.kt b/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/connectionconfig/ConnectionLocationConsistencyHandler.kt new file mode 100644 index 0000000000..7606e11fdf --- /dev/null +++ b/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/connectionconfig/ConnectionLocationConsistencyHandler.kt @@ -0,0 +1,104 @@ +package org.openbase.bco.registry.unit.core.consistency.connectionconfig + +import org.openbase.jul.exception.CouldNotPerformException +import org.openbase.jul.exception.printer.ExceptionPrinter +import org.openbase.jul.extension.protobuf.IdentifiableMessage +import org.openbase.jul.extension.protobuf.container.ProtoBufMessageMap +import org.openbase.jul.storage.registry.AbstractProtoBufRegistryConsistencyHandler +import org.openbase.jul.storage.registry.EntryModification +import org.openbase.jul.storage.registry.ProtoBufFileSynchronizedRegistry +import org.openbase.jul.storage.registry.ProtoBufRegistry +import org.openbase.type.domotic.registry.UnitRegistryDataType.UnitRegistryData +import org.openbase.type.domotic.unit.UnitConfigType.UnitConfig + +/** + * + * @author [Tamino Huxohl](mailto:pleminoq@openbase.org) + */ +class ConnectionLocationConsistencyHandler( + private val locationRegistry: ProtoBufFileSynchronizedRegistry, +) : + AbstractProtoBufRegistryConsistencyHandler() { + @Throws(CouldNotPerformException::class, EntryModification::class) + override fun processData( + id: String, + entry: IdentifiableMessage, + entryMap: ProtoBufMessageMap, + registry: ProtoBufRegistry, + ) { + val connectionUnitConfig = entry.message.toBuilder() + + val locationId: String? = try { + getLowestCommonParentLocation(connectionUnitConfig.connectionConfig.tileIdList, locationRegistry)?.id + } catch (ex: CouldNotPerformException) { + ExceptionPrinter.printHistory( + "Could not find parent location for connection [$connectionUnitConfig]", + ex, + logger + ) + null + } ?: locationRegistry.messages.firstOrNull { it.locationConfig.root }?.id + + locationId?.let { + if (locationId != connectionUnitConfig.placementConfig.locationId) { + val placement = connectionUnitConfig.placementConfig.toBuilder().setLocationId(locationId) + throw EntryModification( + entry.setMessage(connectionUnitConfig.setPlacementConfig(placement), this), + this + ) + } + } + } + + companion object { + fun getLowestCommonParentLocation( + locationIds: List, + locationUnitConfigRegistry: ProtoBufFileSynchronizedRegistry, + ): UnitConfig? { + // list containing the paths from root to each location given by locationIds sorted by the lenght of the path, e.g.: + // home, apartment, hallway, entrance + // home, apartment, outdoor + val pathsFromRootMap: MutableList> = ArrayList() + + // fill the list according to the description above + locationIds.forEach { id -> + var locationUnitConfig = locationUnitConfigRegistry.getMessage(id) + val pathFromRootList: MutableList = ArrayList() + pathFromRootList.add(locationUnitConfig) + while (!locationUnitConfig.locationConfig.root) { + locationUnitConfig = + locationUnitConfigRegistry.getMessage(locationUnitConfig.placementConfig.locationId) + // when adding a location at the front of the list, every entry is moved an index further + pathFromRootList.add(0, locationUnitConfig) + } + pathsFromRootMap.add(pathFromRootList) + } + + // sort the list after their sizes: + // home, apartment, outdoor + // home, apartment, hallway, entrance + pathsFromRootMap.sortWith { o1: List, o2: List -> o2.size - o1.size } + + // find the lowest common parent, e.g. for the example above apartment + // by returning the index before the first elements where the paths differ + + // return null in case connection is not linked to any locations + if (pathsFromRootMap.isEmpty()) { + return null; + } + + val shortestPath = pathsFromRootMap[0].size + (0 until shortestPath).forEach { i -> + val currentId = pathsFromRootMap[0][i].id + (1 until pathsFromRootMap.size).forEach { j -> + if (pathsFromRootMap[j][i].id != currentId) { + return pathsFromRootMap[0][i - 1] + } + } + } + + // checking if a lowest common parent exists should not be necessary since a tile cannot be root + return pathsFromRootMap[0][0] + } + } +} diff --git a/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/connectionconfig/ConnectionTilesConsistencyHandler.java b/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/connectionconfig/ConnectionTilesConsistencyHandler.java deleted file mode 100644 index b903a922bc..0000000000 --- a/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/connectionconfig/ConnectionTilesConsistencyHandler.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.openbase.bco.registry.unit.core.consistency.connectionconfig; - -/* - * #%L - * BCO Registry Unit Core - * %% - * Copyright (C) 2014 - 2021 openbase.org - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * . - * #L% - */ -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import org.openbase.jul.exception.CouldNotPerformException; -import org.openbase.jul.exception.InvalidStateException; -import org.openbase.jul.extension.protobuf.IdentifiableMessage; -import org.openbase.jul.extension.protobuf.container.ProtoBufMessageMap; -import org.openbase.jul.storage.registry.AbstractProtoBufRegistryConsistencyHandler; -import org.openbase.jul.storage.registry.EntryModification; -import org.openbase.jul.storage.registry.ProtoBufFileSynchronizedRegistry; -import org.openbase.jul.storage.registry.ProtoBufRegistry; -import org.openbase.type.domotic.unit.UnitConfigType.UnitConfig; -import org.openbase.type.domotic.registry.UnitRegistryDataType.UnitRegistryData; -import org.openbase.type.domotic.unit.connection.ConnectionConfigType.ConnectionConfig; -import org.openbase.type.domotic.unit.location.LocationConfigType.LocationConfig; - -/** - * - * @author Tamino Huxohl - */ -public class ConnectionTilesConsistencyHandler extends AbstractProtoBufRegistryConsistencyHandler { - - private final ProtoBufFileSynchronizedRegistry locationRegistry; - - public ConnectionTilesConsistencyHandler(ProtoBufFileSynchronizedRegistry locationRegistry) { - this.locationRegistry = locationRegistry; - } - - @Override - public void processData(String id, IdentifiableMessage entry, ProtoBufMessageMap entryMap, ProtoBufRegistry registry) throws CouldNotPerformException, EntryModification { - UnitConfig.Builder connectionUnitConfig = entry.getMessage().toBuilder(); - ConnectionConfig.Builder connectionConfig = connectionUnitConfig.getConnectionConfigBuilder(); - - - if (connectionConfig.getTileIdList().size() < 2) { - throw new InvalidStateException("Connections must connect at least 2 tiles which is not true for connection [" + entry.getMessage() + "] which is connecting only "+connectionConfig.getTileIdList().size()+"!"); - } - - boolean modification = false; - connectionConfig.clearTileId(); - // remove duplicated entries and location ids that are not tiles - Map tileIds = new HashMap<>(); - for (String tileId : entry.getMessage().getConnectionConfig().getTileIdList()) { - UnitConfig location = null; - if (locationRegistry.contains(tileId)) { - location = locationRegistry.get(tileId).getMessage(); - } - if (location != null && location.getLocationConfig().hasLocationType() && location.getLocationConfig().getLocationType() == LocationConfig.LocationType.TILE) { - tileIds.put(tileId, tileId); - } else { - modification = true; - } - } - connectionConfig.addAllTileId(new ArrayList<>(tileIds.keySet())); - - if (modification) { - throw new EntryModification(entry.setMessage(connectionUnitConfig, this), this); - } - } -} diff --git a/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/connectionconfig/ConnectionTilesConsistencyHandler.kt b/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/connectionconfig/ConnectionTilesConsistencyHandler.kt new file mode 100644 index 0000000000..309ea7a810 --- /dev/null +++ b/module/registry/unit-registry/core/src/main/java/org/openbase/bco/registry/unit/core/consistency/connectionconfig/ConnectionTilesConsistencyHandler.kt @@ -0,0 +1,42 @@ +package org.openbase.bco.registry.unit.core.consistency.connectionconfig + +import org.openbase.jul.exception.CouldNotPerformException +import org.openbase.jul.extension.protobuf.IdentifiableMessage +import org.openbase.jul.extension.protobuf.container.ProtoBufMessageMap +import org.openbase.jul.storage.registry.AbstractProtoBufRegistryConsistencyHandler +import org.openbase.jul.storage.registry.EntryModification +import org.openbase.jul.storage.registry.ProtoBufFileSynchronizedRegistry +import org.openbase.jul.storage.registry.ProtoBufRegistry +import org.openbase.type.domotic.registry.UnitRegistryDataType +import org.openbase.type.domotic.unit.UnitConfigType +import org.openbase.type.domotic.unit.location.LocationConfigType.LocationConfig.LocationType + +/** + * + * @author [Tamino Huxohl](mailto:pleminoq@openbase.org) + */ +class ConnectionTilesConsistencyHandler(private val locationRegistry: ProtoBufFileSynchronizedRegistry) : + AbstractProtoBufRegistryConsistencyHandler() { + @Throws(CouldNotPerformException::class, EntryModification::class) + override fun processData( + id: String, + entry: IdentifiableMessage, + entryMap: ProtoBufMessageMap, + registry: ProtoBufRegistry, + ) { + val connectionUnitConfig = entry.message.toBuilder() + val connectionConfig = connectionUnitConfig.connectionConfigBuilder + + // remove duplicated entries and location ids that are not tiles + entry.message.connectionConfig.tileIdList + .distinct() + .filter { tileId -> locationRegistry[tileId].message?.locationConfig?.locationType == LocationType.TILE } + .let { tileIds -> + if (connectionConfig.tileIdList.toList().sorted() != tileIds.sorted()) { + connectionConfig.clearTileId() + connectionConfig.addAllTileId(tileIds) + throw EntryModification(entry.setMessage(connectionUnitConfig, this), this) + } + } + } +}