From fc7e3dc61a2ac8de32914af331c1144e4fa843e6 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Sat, 19 Aug 2023 03:00:23 +0200 Subject: refactor: remove unused VIATRA code We don't need Eclipse platform support, table-based scopes, and EMF support. --- subprojects/viatra-runtime-base/about.html | 26 - subprojects/viatra-runtime-base/build.gradle.kts | 19 - .../viatra/runtime/base/ViatraBasePlugin.java | 46 - .../viatra/runtime/base/api/BaseIndexOptions.java | 395 ----- .../viatra/runtime/base/api/DataTypeListener.java | 44 - .../base/api/EMFBaseIndexChangeListener.java | 33 - .../viatra/runtime/base/api/FeatureListener.java | 48 - .../runtime/base/api/IEClassifierProcessor.java | 25 - .../base/api/IEMFIndexingErrorListener.java | 22 - .../runtime/base/api/IQueryResultSetter.java | 63 - .../base/api/IQueryResultUpdateListener.java | 45 - .../api/IStructuralFeatureInstanceProcessor.java | 19 - .../viatra/runtime/base/api/IndexingLevel.java | 113 -- .../viatra/runtime/base/api/InstanceListener.java | 41 - .../base/api/LightweightEObjectObserver.java | 32 - .../api/LightweightEObjectObserverAdapter.java | 74 - .../viatra/runtime/base/api/NavigationHelper.java | 885 ---------- .../base/api/QueryResultAssociativeStore.java | 322 ---- .../viatra/runtime/base/api/QueryResultMap.java | 210 --- .../runtime/base/api/TransitiveClosureHelper.java | 26 - .../viatra/runtime/base/api/ViatraBaseFactory.java | 180 --- .../base/api/filters/IBaseIndexFeatureFilter.java | 38 - .../base/api/filters/IBaseIndexObjectFilter.java | 30 - .../base/api/filters/IBaseIndexResourceFilter.java | 27 - .../base/api/filters/SimpleBaseIndexFilter.java | 46 - .../base/api/profiler/BaseIndexProfiler.java | 79 - .../runtime/base/api/profiler/ProfilerMode.java | 22 - .../base/comprehension/EMFModelComprehension.java | 356 ---- .../runtime/base/comprehension/EMFVisitor.java | 145 -- .../WellbehavingDerivedFeatureRegistry.java | 154 -- .../runtime/base/core/AbstractBaseIndexStore.java | 28 - .../base/core/EMFBaseIndexInstanceStore.java | 451 ------ .../runtime/base/core/EMFBaseIndexMetaStore.java | 380 ----- .../base/core/EMFBaseIndexStatisticsStore.java | 71 - .../viatra/runtime/base/core/EMFDataSource.java | 137 -- .../base/core/NavigationHelperContentAdapter.java | 750 --------- .../runtime/base/core/NavigationHelperImpl.java | 1702 -------------------- .../runtime/base/core/NavigationHelperSetting.java | 73 - .../runtime/base/core/NavigationHelperType.java | 14 - .../runtime/base/core/NavigationHelperVisitor.java | 441 ----- .../base/core/TransitiveClosureHelperImpl.java | 153 -- .../ProfilingNavigationHelperContentAdapter.java | 155 -- .../base/exception/ViatraBaseException.java | 25 - .../viatra-runtime-localsearch/build.gradle.kts | 1 - .../localsearch/ExecutionLoggerAdapter.java | 26 +- .../viatra/runtime/localsearch/MatchingFrame.java | 32 +- .../localsearch/matcher/ISearchContext.java | 61 +- .../LocalSearchBackendFactoryProvider.java | 29 - .../integration/LocalSearchEMFBackendFactory.java | 65 - .../matcher/integration/LocalSearchHints.java | 157 +- .../integration/LocalSearchResultProvider.java | 56 - .../operations/check/ContainmentCheck.java | 85 - .../operations/check/InstanceOfClassCheck.java | 75 - .../operations/check/InstanceOfDataTypeCheck.java | 71 - .../operations/check/InstanceOfJavaClassCheck.java | 71 - .../operations/check/StructuralFeatureCheck.java | 91 -- .../operations/check/nobase/ScopeCheck.java | 91 -- .../extend/ExtendToEStructuralFeatureSource.java | 112 -- .../extend/ExtendToEStructuralFeatureTarget.java | 102 -- .../operations/extend/IterateOverChildren.java | 90 -- .../operations/extend/IterateOverContainers.java | 126 -- .../extend/IterateOverEClassInstances.java | 97 -- .../extend/IterateOverEDatatypeInstances.java | 96 -- .../IterateOverEStructuralFeatureInstances.java | 115 -- .../AbstractIteratingExtendOperationExecutor.java | 54 - .../nobase/ExtendToEStructuralFeatureSource.java | 118 -- .../extend/nobase/IterateOverEClassInstances.java | 93 -- .../nobase/IterateOverEDatatypeInstances.java | 123 -- .../planner/PConstraintInfoInferrer.java | 158 +- .../planner/compiler/EMFOperationCompiler.java | 198 --- .../runtime/matchers/scopes/IStorageBackend.java | 53 - .../matchers/scopes/SimpleLocalStorageBackend.java | 51 - .../matchers/scopes/SimpleRuntimeContext.java | 132 -- .../matchers/scopes/TabularRuntimeContext.java | 119 -- .../matchers/scopes/tables/AbstractIndexTable.java | 266 --- .../matchers/scopes/tables/DefaultIndexTable.java | 143 -- .../matchers/scopes/tables/DisjointUnionTable.java | 192 --- .../matchers/scopes/tables/IIndexTable.java | 212 --- .../matchers/scopes/tables/ITableContext.java | 29 - .../matchers/scopes/tables/ITableWriterBinary.java | 53 - .../scopes/tables/ITableWriterGeneric.java | 52 - .../matchers/scopes/tables/ITableWriterUnary.java | 52 - .../matchers/scopes/tables/SimpleBinaryTable.java | 320 ---- .../matchers/scopes/tables/SimpleUnaryTable.java | 140 -- subprojects/viatra-runtime/build.gradle.kts | 6 +- .../tools/refinery/viatra/runtime/IExtensions.java | 24 - .../viatra/runtime/ViatraQueryRuntimePlugin.java | 32 - .../runtime/api/AdvancedViatraQueryEngine.java | 163 +- .../runtime/api/IModelConnectorTypeEnum.java | 18 - .../viatra/runtime/api/IQuerySpecification.java | 37 +- .../viatra/runtime/api/IRunOnceQueryEngine.java | 68 - .../viatra/runtime/api/LazyLoadingQueryGroup.java | 64 - .../viatra/runtime/api/PackageBasedQueryGroup.java | 133 -- .../viatra/runtime/api/ViatraQueryEngine.java | 2 - .../runtime/api/ViatraQueryEngineManager.java | 77 +- .../runtime/api/impl/BaseGeneratedEMFPQuery.java | 110 -- .../impl/BaseGeneratedEMFQuerySpecification.java | 40 - ...tedEMFQuerySpecificationWithGenericMatcher.java | 58 - .../viatra/runtime/api/impl/BasePatternMatch.java | 40 +- .../runtime/api/impl/RunOnceQueryEngine.java | 140 -- .../runtime/api/scope/IIndexingErrorListener.java | 8 +- .../runtime/emf/DynamicEMFQueryRuntimeContext.java | 47 - .../viatra/runtime/emf/EMFBaseIndexWrapper.java | 160 -- .../viatra/runtime/emf/EMFEngineContext.java | 110 -- .../viatra/runtime/emf/EMFQueryMetaContext.java | 405 ----- .../viatra/runtime/emf/EMFQueryRuntimeContext.java | 839 ---------- .../refinery/viatra/runtime/emf/EMFScope.java | 199 --- .../emf/helper/ViatraQueryRuntimeHelper.java | 161 -- .../viatra/runtime/emf/types/BaseEMFTypeKey.java | 34 - .../runtime/emf/types/EClassExactInstancesKey.java | 51 - .../emf/types/EClassTransitiveInstancesKey.java | 47 - .../EClassUnscopedTransitiveInstancesKey.java | 46 - .../runtime/emf/types/EDataTypeInSlotsKey.java | 48 - .../emf/types/EStructuralFeatureInstancesKey.java | 48 - .../runtime/extensibility/IQueryGroupProvider.java | 40 - .../extensibility/IQuerySpecificationProvider.java | 36 - .../extensibility/PQueryExtensionFactory.java | 33 - .../extensibility/SingletonExtensionFactory.java | 62 - .../extensibility/SingletonQueryGroupProvider.java | 46 - .../SingletonQuerySpecificationProvider.java | 42 - .../extensibility/ViatraQueryRuntimeConstants.java | 27 - .../ExtensionBasedSurrogateQueryLoader.java | 148 -- .../ExtensionBasedSystemDefaultBackendLoader.java | 60 - .../internal/apiimpl/ViatraQueryEngineImpl.java | 15 +- .../ExtensionBasedQuerySpecificationLoader.java | 303 ---- .../runtime/registry/IConnectorListener.java | 40 - .../runtime/registry/IDefaultRegistryView.java | 37 - .../registry/IQuerySpecificationRegistry.java | 74 - .../IQuerySpecificationRegistryChangeListener.java | 35 - .../registry/IQuerySpecificationRegistryEntry.java | 48 - .../runtime/registry/IRegistrySourceConnector.java | 50 - .../viatra/runtime/registry/IRegistryView.java | 72 - .../runtime/registry/IRegistryViewFactory.java | 34 - .../runtime/registry/IRegistryViewFilter.java | 33 - .../registry/QuerySpecificationRegistry.java | 112 -- .../connector/AbstractRegistrySourceConnector.java | 81 - .../QueryGroupProviderSourceConnector.java | 80 - .../connector/SpecificationMapSourceConnector.java | 147 -- .../registry/data/QuerySpecificationStore.java | 38 - .../runtime/registry/data/RegistryEntryImpl.java | 81 - .../runtime/registry/data/RegistrySourceImpl.java | 73 - .../registry/impl/FilteringRegistryView.java | 43 - .../runtime/registry/impl/GlobalRegistryView.java | 65 - .../impl/QuerySpecificationRegistryImpl.java | 177 -- .../registry/impl/RegistryChangeMultiplexer.java | 58 - .../registry/view/AbstractRegistryView.java | 150 -- .../viatra/runtime/tabular/EcoreIndexHost.java | 166 -- .../runtime/tabular/TabularEngineContext.java | 107 -- .../viatra/runtime/tabular/TabularIndexHost.java | 145 -- 149 files changed, 298 insertions(+), 17827 deletions(-) delete mode 100644 subprojects/viatra-runtime-base/about.html delete mode 100644 subprojects/viatra-runtime-base/build.gradle.kts delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/ViatraBasePlugin.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/BaseIndexOptions.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/DataTypeListener.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/EMFBaseIndexChangeListener.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/FeatureListener.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IEClassifierProcessor.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IEMFIndexingErrorListener.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IQueryResultSetter.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IQueryResultUpdateListener.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IStructuralFeatureInstanceProcessor.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IndexingLevel.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/InstanceListener.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/LightweightEObjectObserver.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/LightweightEObjectObserverAdapter.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/NavigationHelper.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/QueryResultAssociativeStore.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/QueryResultMap.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/TransitiveClosureHelper.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/ViatraBaseFactory.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/filters/IBaseIndexFeatureFilter.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/filters/IBaseIndexObjectFilter.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/filters/IBaseIndexResourceFilter.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/filters/SimpleBaseIndexFilter.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/profiler/BaseIndexProfiler.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/profiler/ProfilerMode.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/comprehension/EMFModelComprehension.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/comprehension/EMFVisitor.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/comprehension/WellbehavingDerivedFeatureRegistry.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/AbstractBaseIndexStore.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/EMFBaseIndexInstanceStore.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/EMFBaseIndexMetaStore.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/EMFBaseIndexStatisticsStore.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/EMFDataSource.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperContentAdapter.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperImpl.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperSetting.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperType.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperVisitor.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/TransitiveClosureHelperImpl.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/profiler/ProfilingNavigationHelperContentAdapter.java delete mode 100644 subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/exception/ViatraBaseException.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchBackendFactoryProvider.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchEMFBackendFactory.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchResultProvider.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/ContainmentCheck.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/InstanceOfClassCheck.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/InstanceOfDataTypeCheck.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/InstanceOfJavaClassCheck.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/StructuralFeatureCheck.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/nobase/ScopeCheck.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/ExtendToEStructuralFeatureSource.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/ExtendToEStructuralFeatureTarget.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverChildren.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverContainers.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverEClassInstances.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverEDatatypeInstances.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverEStructuralFeatureInstances.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/nobase/AbstractIteratingExtendOperationExecutor.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/nobase/ExtendToEStructuralFeatureSource.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/nobase/IterateOverEClassInstances.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/nobase/IterateOverEDatatypeInstances.java delete mode 100644 subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/planner/compiler/EMFOperationCompiler.java delete mode 100644 subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/IStorageBackend.java delete mode 100644 subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/SimpleLocalStorageBackend.java delete mode 100644 subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/SimpleRuntimeContext.java delete mode 100644 subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/TabularRuntimeContext.java delete mode 100644 subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/AbstractIndexTable.java delete mode 100644 subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/DefaultIndexTable.java delete mode 100644 subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/DisjointUnionTable.java delete mode 100644 subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/IIndexTable.java delete mode 100644 subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/ITableContext.java delete mode 100644 subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/ITableWriterBinary.java delete mode 100644 subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/ITableWriterGeneric.java delete mode 100644 subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/ITableWriterUnary.java delete mode 100644 subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/SimpleBinaryTable.java delete mode 100644 subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/SimpleUnaryTable.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/IExtensions.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/ViatraQueryRuntimePlugin.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/IModelConnectorTypeEnum.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/IRunOnceQueryEngine.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/LazyLoadingQueryGroup.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/PackageBasedQueryGroup.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/BaseGeneratedEMFPQuery.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/BaseGeneratedEMFQuerySpecification.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/BaseGeneratedEMFQuerySpecificationWithGenericMatcher.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/RunOnceQueryEngine.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/DynamicEMFQueryRuntimeContext.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFBaseIndexWrapper.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFEngineContext.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFQueryMetaContext.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFQueryRuntimeContext.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFScope.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/helper/ViatraQueryRuntimeHelper.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/BaseEMFTypeKey.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EClassExactInstancesKey.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EClassTransitiveInstancesKey.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EClassUnscopedTransitiveInstancesKey.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EDataTypeInSlotsKey.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EStructuralFeatureInstancesKey.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/IQueryGroupProvider.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/IQuerySpecificationProvider.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/PQueryExtensionFactory.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/SingletonExtensionFactory.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/SingletonQueryGroupProvider.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/SingletonQuerySpecificationProvider.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/ViatraQueryRuntimeConstants.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/internal/ExtensionBasedSurrogateQueryLoader.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/internal/ExtensionBasedSystemDefaultBackendLoader.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/ExtensionBasedQuerySpecificationLoader.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IConnectorListener.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IDefaultRegistryView.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IQuerySpecificationRegistry.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IQuerySpecificationRegistryChangeListener.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IQuerySpecificationRegistryEntry.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IRegistrySourceConnector.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IRegistryView.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IRegistryViewFactory.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IRegistryViewFilter.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/QuerySpecificationRegistry.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/connector/AbstractRegistrySourceConnector.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/connector/QueryGroupProviderSourceConnector.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/connector/SpecificationMapSourceConnector.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/data/QuerySpecificationStore.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/data/RegistryEntryImpl.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/data/RegistrySourceImpl.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/FilteringRegistryView.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/GlobalRegistryView.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/QuerySpecificationRegistryImpl.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/RegistryChangeMultiplexer.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/view/AbstractRegistryView.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/tabular/EcoreIndexHost.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/tabular/TabularEngineContext.java delete mode 100644 subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/tabular/TabularIndexHost.java (limited to 'subprojects') diff --git a/subprojects/viatra-runtime-base/about.html b/subprojects/viatra-runtime-base/about.html deleted file mode 100644 index d1d5593a..00000000 --- a/subprojects/viatra-runtime-base/about.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - -About - - - -

About This Content

- -

March 18, 2019

-

License

- -

The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the -Eclipse Public License Version 2.0 ("EPL"). A copy of the EPL is available at http://www.eclipse.org/legal/epl-v20.html. -For purposes of the EPL, "Program" will mean the Content.

- -

If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party ("Redistributor") and different terms and conditions may -apply to your use of any object code in the Content. Check the Redistributor's license that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise -indicated below, the terms and conditions of the EPL still apply to any source code in the Content and such source code may be obtained at http://www.eclipse.org.

- - diff --git a/subprojects/viatra-runtime-base/build.gradle.kts b/subprojects/viatra-runtime-base/build.gradle.kts deleted file mode 100644 index 55c6acb8..00000000 --- a/subprojects/viatra-runtime-base/build.gradle.kts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors - * - * SPDX-License-Identifier: EPL-2.0 - */ - -plugins { - id("tools.refinery.gradle.java-library") -} - -dependencies { - api(project(":refinery-viatra-runtime-base-itc")) - api(project(":refinery-viatra-runtime-matchers")) - implementation(libs.eclipse) - implementation(libs.ecore) - implementation(libs.emf) - implementation(libs.osgi) - implementation(libs.slf4j.log4j) -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/ViatraBasePlugin.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/ViatraBasePlugin.java deleted file mode 100644 index 96b40825..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/ViatraBasePlugin.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.base; - -import org.eclipse.core.runtime.Plugin; -import tools.refinery.viatra.runtime.base.comprehension.WellbehavingDerivedFeatureRegistry; -import org.osgi.framework.BundleContext; - -public class ViatraBasePlugin extends Plugin { - - // The shared instance - private static ViatraBasePlugin plugin; - - public static final String PLUGIN_ID = "tools.refinery.viatra.runtime.base"; - public static final String WELLBEHAVING_DERIVED_FEATURE_EXTENSION_POINT_ID = "tools.refinery.viatra.runtime.base.wellbehaving.derived.features"; - - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - plugin = this; - WellbehavingDerivedFeatureRegistry.initRegistry(); - } - - @Override - public void stop(BundleContext context) throws Exception { - plugin = null; - super.stop(context); - } - - /** - * Returns the shared instance - * - * @return the shared instance - */ - public static ViatraBasePlugin getDefault() { - return plugin; - } - -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/BaseIndexOptions.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/BaseIndexOptions.java deleted file mode 100644 index 92663400..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/BaseIndexOptions.java +++ /dev/null @@ -1,395 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Abel Hegedus, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api; - -import java.util.Objects; - -import tools.refinery.viatra.runtime.base.api.filters.IBaseIndexFeatureFilter; -import tools.refinery.viatra.runtime.base.api.filters.IBaseIndexObjectFilter; -import tools.refinery.viatra.runtime.base.api.filters.IBaseIndexResourceFilter; -import tools.refinery.viatra.runtime.base.api.profiler.ProfilerMode; - -/** - * The base index options indicate how the indices are built. - * - *

- * One of the options is to build indices in wildcard mode, meaning that all EClasses, EDataTypes, EReferences - * and EAttributes are indexed. This is convenient, but comes at a high memory cost. To save memory, one can disable - * wildcard mode and manually register those EClasses, EDataTypes, EReferences and EAttributes that should be - * indexed. - *

- * - *

- * Another choice is whether to build indices in dynamic EMF mode, meaning that types are identified by the - * String IDs that are ultimately derived from the nsURI of the EPackage. Multiple types with the same ID are treated as - * the same. This is useful if dynamic EMF is used, where there can be multiple copies (instantiations) of the same - * EPackage, representing essentially the same metamodel. If one disables dynamic EMF mode, an error is logged - * if duplicate EPackages with the same nsURI are encountered. - *

- * - * @author Abel Hegedus - * @noimplement This class is not intended to be subclasses outside of VIATRA runtime - * - */ -public class BaseIndexOptions { - - /** - * - * By default, base indices will be constructed with wildcard mode set as false. - */ - protected static final IndexingLevel WILDCARD_MODE_DEFAULT = IndexingLevel.NONE; - /** - * - * By default, base indices will be constructed with only well-behaving features traversed. - */ - private static final boolean TRAVERSE_ONLY_WELLBEHAVING_DERIVED_FEATURES_DEFAULT = true; - /** - * - * By default, base indices will be constructed with dynamic EMF mode set as false. - */ - protected static final boolean DYNAMIC_EMF_MODE_DEFAULT = false; - - /** - * - * By default, the scope will make the assumption that it is free from dangling edges. - * @since 1.6 - */ - protected static final boolean DANGLING_FREE_ASSUMPTION_DEFAULT = true; - - /** - * By default, duplicate notifications are only logged. - * - * @since 1.6 - */ - protected static final boolean STRICT_NOTIFICATION_MODE_DEFAULT = true; - - /** - * @since 2.3 - */ - protected static final ProfilerMode INDEX_PROFILER_MODE_DEFAULT = ProfilerMode.OFF; - - /** - * @since 1.6 - */ - protected boolean danglingFreeAssumption = DANGLING_FREE_ASSUMPTION_DEFAULT; - protected boolean dynamicEMFMode = DYNAMIC_EMF_MODE_DEFAULT; - protected boolean traverseOnlyWellBehavingDerivedFeatures = TRAVERSE_ONLY_WELLBEHAVING_DERIVED_FEATURES_DEFAULT; - protected IndexingLevel wildcardMode = WILDCARD_MODE_DEFAULT; - protected IBaseIndexObjectFilter notifierFilterConfiguration; - protected IBaseIndexResourceFilter resourceFilterConfiguration; - /** - * @since 1.5 - */ - protected IBaseIndexFeatureFilter featureFilterConfiguration; - - /** - * If strict notification mode is turned on, errors related to inconsistent notifications, e.g. duplicate deletions - * cause the entire Base index to be considered invalid, e.g. the query engine on top of the index should become - * tainted. - * - * @since 1.6 - */ - protected boolean strictNotificationMode = STRICT_NOTIFICATION_MODE_DEFAULT; - - /** - * Returns whether base index profiling should be turned on. - * - * @since 2.3 - */ - protected ProfilerMode indexerProfilerMode = INDEX_PROFILER_MODE_DEFAULT; - - /** - * Creates a base index options with the default values. - */ - public BaseIndexOptions() { - } - - /** - * Creates a base index options using the provided values for dynamic EMF mode and wildcard mode. - * @since 1.4 - */ - public BaseIndexOptions(boolean dynamicEMFMode, IndexingLevel wildcardMode) { - this.dynamicEMFMode = dynamicEMFMode; - this.wildcardMode = wildcardMode; - } - - /** - * - * @param dynamicEMFMode - * @since 0.9 - */ - public BaseIndexOptions withDynamicEMFMode(boolean dynamicEMFMode) { - BaseIndexOptions result = copy(); - result.dynamicEMFMode = dynamicEMFMode; - return result; - } - - /** - * Sets the dangling edge handling property of the index option. If not set explicitly, it is considered as `true`. - * @param danglingFreeAssumption if true, - * the base index will assume that there are no dangling references - * (pointing out of scope or to proxies) - * @since 1.6 - */ - public BaseIndexOptions withDanglingFreeAssumption(boolean danglingFreeAssumption) { - BaseIndexOptions result = copy(); - result.danglingFreeAssumption = danglingFreeAssumption; - return result; - } - - /** - * Adds an object-level filter to the indexer configuration. Warning - object-level indexing can increase indexing time - * noticeably. If possibly, use {@link #withResourceFilterConfiguration(IBaseIndexResourceFilter)} instead. - * - * @param filter - * @since 0.9 - */ - public BaseIndexOptions withObjectFilterConfiguration(IBaseIndexObjectFilter filter) { - BaseIndexOptions result = copy(); - result.notifierFilterConfiguration = filter; - return result; - } - - /** - * @return the selected object filter configuration, or null if not set - */ - public IBaseIndexObjectFilter getObjectFilterConfiguration() { - return notifierFilterConfiguration; - } - - /** - * Returns a copy of the configuration with a specified resource filter - * - * @param filter - * @since 0.9 - */ - public BaseIndexOptions withResourceFilterConfiguration(IBaseIndexResourceFilter filter) { - BaseIndexOptions result = copy(); - result.resourceFilterConfiguration = filter; - return result; - } - - /** - * @return the selected resource filter, or null if not set - */ - public IBaseIndexResourceFilter getResourceFilterConfiguration() { - return resourceFilterConfiguration; - } - - - /** - * Returns a copy of the configuration with a specified feature filter - * - * @param filter - * @since 1.5 - */ - public BaseIndexOptions withFeatureFilterConfiguration(IBaseIndexFeatureFilter filter) { - BaseIndexOptions result = copy(); - result.featureFilterConfiguration = filter; - return result; - } - - /** - * @return the selected feature filter, or null if not set - * @since 1.5 - */ - public IBaseIndexFeatureFilter getFeatureFilterConfiguration() { - return featureFilterConfiguration; - } - - - /** - * @return whether the base index option has dynamic EMF mode set - */ - public boolean isDynamicEMFMode() { - return dynamicEMFMode; - } - - /** - * @return whether the base index makes the assumption that there can be no dangling edges - * @since 1.6 - */ - public boolean isDanglingFreeAssumption() { - return danglingFreeAssumption; - } - - /** - * @return whether the base index option has traverse only well-behaving derived features set - */ - public boolean isTraverseOnlyWellBehavingDerivedFeatures() { - return traverseOnlyWellBehavingDerivedFeatures; - } - - /** - * - * @param wildcardMode - * @since 1.4 - */ - public BaseIndexOptions withWildcardLevel(IndexingLevel wildcardLevel) { - BaseIndexOptions result = copy(); - result.wildcardMode = wildcardLevel; - return result; - } - - /** - * @since 1.6 - */ - public BaseIndexOptions withStrictNotificationMode(boolean strictNotificationMode) { - BaseIndexOptions result = copy(); - result.strictNotificationMode = strictNotificationMode; - return result; - } - - /** - * @since 2.3 - */ - public BaseIndexOptions withIndexProfilerMode(ProfilerMode indexerProfilerMode) { - BaseIndexOptions result = copy(); - result.indexerProfilerMode = indexerProfilerMode; - return result; - } - - /** - * @return whether the base index option has wildcard mode set - */ - public boolean isWildcardMode() { - return wildcardMode == IndexingLevel.FULL; - } - - /** - * @return the wildcardMode level - * @since 1.4 - */ - public IndexingLevel getWildcardLevel() { - return wildcardMode; - } - - /** - * If strict notification mode is turned on, errors related to inconsistent notifications, e.g. duplicate deletions - * cause the entire Base index to be considered invalid, e.g. the query engine on top of the index should become - * tainted. - * - * @since 1.6 - */ - public boolean isStrictNotificationMode() { - return strictNotificationMode; - } - - /** - * Returns whether base indexer profiling is enabled. The profiling causes some slowdown, but provides information - * about how much time the base indexer takes for initialization and updates. - * - * @since 2.3 - */ - public ProfilerMode getIndexerProfilerMode() { - return indexerProfilerMode; - } - - /** - * Creates an independent copy of itself. The values of each option will be the same as this options. This method is - * used when a provided option must be copied to avoid external option changes afterward. - * - * @return the copy of this options - */ - public BaseIndexOptions copy() { - BaseIndexOptions baseIndexOptions = new BaseIndexOptions(this.dynamicEMFMode, this.wildcardMode); - baseIndexOptions.danglingFreeAssumption = this.danglingFreeAssumption; - baseIndexOptions.traverseOnlyWellBehavingDerivedFeatures = this.traverseOnlyWellBehavingDerivedFeatures; - baseIndexOptions.notifierFilterConfiguration = this.notifierFilterConfiguration; - baseIndexOptions.resourceFilterConfiguration = this.resourceFilterConfiguration; - baseIndexOptions.featureFilterConfiguration = this.featureFilterConfiguration; - baseIndexOptions.strictNotificationMode = this.strictNotificationMode; - baseIndexOptions.indexerProfilerMode = this.indexerProfilerMode; - return baseIndexOptions; - } - - @Override - public int hashCode() { - return Objects.hash(dynamicEMFMode, notifierFilterConfiguration, resourceFilterConfiguration, - featureFilterConfiguration, traverseOnlyWellBehavingDerivedFeatures, wildcardMode, strictNotificationMode, - danglingFreeAssumption, indexerProfilerMode); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (!(obj instanceof BaseIndexOptions)) - return false; - BaseIndexOptions other = (BaseIndexOptions) obj; - if (dynamicEMFMode != other.dynamicEMFMode) - return false; - if (danglingFreeAssumption != other.danglingFreeAssumption) - return false; - if (notifierFilterConfiguration == null) { - if (other.notifierFilterConfiguration != null) - return false; - } else if (!notifierFilterConfiguration - .equals(other.notifierFilterConfiguration)) - return false; - if (resourceFilterConfiguration == null) { - if (other.resourceFilterConfiguration != null) - return false; - } else if (!resourceFilterConfiguration - .equals(other.resourceFilterConfiguration)){ - return false; - } - - if (featureFilterConfiguration == null) { - if (other.featureFilterConfiguration != null) - return false; - } else if (!featureFilterConfiguration - .equals(other.featureFilterConfiguration)){ - return false; - } - - if (traverseOnlyWellBehavingDerivedFeatures != other.traverseOnlyWellBehavingDerivedFeatures) - return false; - if (wildcardMode != other.wildcardMode) - return false; - if (strictNotificationMode != other.strictNotificationMode) { - return false; - } - if (indexerProfilerMode != other.indexerProfilerMode) { - return false; - } - return true; - } - - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - appendModifier(sb, dynamicEMFMode, DYNAMIC_EMF_MODE_DEFAULT, "dynamicEMF"); - appendModifier(sb, wildcardMode, WILDCARD_MODE_DEFAULT, "wildcard"); - appendModifier(sb, danglingFreeAssumption, DANGLING_FREE_ASSUMPTION_DEFAULT, "danglingFreeAssumption"); - appendModifier(sb, traverseOnlyWellBehavingDerivedFeatures, TRAVERSE_ONLY_WELLBEHAVING_DERIVED_FEATURES_DEFAULT, "wellBehavingOnly"); - appendModifier(sb, strictNotificationMode, STRICT_NOTIFICATION_MODE_DEFAULT, "strictNotificationMode"); - appendModifier(sb, indexerProfilerMode, INDEX_PROFILER_MODE_DEFAULT, "indexerProfilerMode"); - appendModifier(sb, notifierFilterConfiguration, null, "notifierFilter="); - appendModifier(sb, resourceFilterConfiguration, null, "resourceFilter="); - appendModifier(sb, featureFilterConfiguration, null, "featureFilterConfiguration="); - final String result = sb.toString(); - return result.isEmpty() ? "defaults" : result; - } - - private static void appendModifier(StringBuilder sb, Object actualValue, Object expectedValue, String switchName) { - if (Objects.equals(expectedValue, actualValue)) { - // silent - } else { - sb.append(Boolean.FALSE.equals(actualValue) ? '-' : '+'); - sb.append(switchName); - if (! (actualValue instanceof Boolean)) - sb.append(actualValue); - } - } - -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/DataTypeListener.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/DataTypeListener.java deleted file mode 100644 index 3d30df5e..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/DataTypeListener.java +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api; - -import org.eclipse.emf.ecore.EDataType; - -/** - * Interface for observing insertion and deletion of instances of data types. - * - * @author Tamas Szabo - * - */ -public interface DataTypeListener { - - /** - * Called when an instance of the given type is inserted. - * - * @param type - * the {@link EDataType} - * @param instance - * the instance of the data type - * @param firstOccurrence - * true if this value was not previously present in the model - */ - public void dataTypeInstanceInserted(EDataType type, Object instance, boolean firstOccurrence); - - /** - * Called when an instance of the given type is deleted. - * - * @param type - * the {@link EDataType} - * @param instance - * the instance of the data type - * @param lastOccurrence - * true if this value is no longer present in the model - */ - public void dataTypeInstanceDeleted(EDataType type, Object instance, boolean lastOccurrence); -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/EMFBaseIndexChangeListener.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/EMFBaseIndexChangeListener.java deleted file mode 100644 index 5a2486f9..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/EMFBaseIndexChangeListener.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Abel Hegedus, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api; - -/** - * Listener interface for change notifications from the VIATRA Base index. - * - * @author Abel Hegedus - * - */ -public interface EMFBaseIndexChangeListener { - - /** - * NOTE: it is possible that this method is called only ONCE! Consider returning a constant value that is set in the constructor. - * - * @return true, if the listener should be notified only after index changes, false if notification is needed after each model change - */ - public boolean onlyOnIndexChange(); - - /** - * Called after a model change is handled by the VIATRA Base index and if indexChanged == onlyOnIndexChange(). - * - * @param indexChanged true, if the model change also affected the contents of the base index - */ - public void notifyChanged(boolean indexChanged); - -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/FeatureListener.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/FeatureListener.java deleted file mode 100644 index fa2d679e..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/FeatureListener.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api; - -import org.eclipse.emf.ecore.EAttribute; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.emf.ecore.EStructuralFeature; - -/** - * Interface for observing insertion and deletion of structural feature values ("settings"). (Works both for - * single-valued and many-valued features.) - * - * @author Tamas Szabo - * - */ -public interface FeatureListener { - - /** - * Called when the given value is inserted into the given feature of the given host EObject. - * - * @param host - * the host (holder) of the feature - * @param feature - * the {@link EAttribute} or {@link EReference} instance - * @param value - * the target of the feature - */ - public void featureInserted(EObject host, EStructuralFeature feature, Object value); - - /** - * Called when the given value is removed from the given feature of the given host EObject. - * - * @param host - * the host (holder) of the feature - * @param feature - * the {@link EAttribute} or {@link EReference} instance - * @param value - * the target of the feature - */ - public void featureDeleted(EObject host, EStructuralFeature feature, Object value); -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IEClassifierProcessor.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IEClassifierProcessor.java deleted file mode 100644 index aaa98918..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IEClassifierProcessor.java +++ /dev/null @@ -1,25 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Abel Hegedus, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api; - -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EDataType; -import org.eclipse.emf.ecore.EObject; - -/** - * @author Abel Hegedus - * - */ -public interface IEClassifierProcessor { - - void process(ClassType type, InstanceType instance); - - public interface IEClassProcessor extends IEClassifierProcessor{} - public interface IEDataTypeProcessor extends IEClassifierProcessor{} -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IEMFIndexingErrorListener.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IEMFIndexingErrorListener.java deleted file mode 100644 index 1dc3291b..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IEMFIndexingErrorListener.java +++ /dev/null @@ -1,22 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2014, Zoltan Ujhelyi, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api; - -/** - * - * This interface contains callbacks for various internal errors from the {@link NavigationHelper base index}. - * - * @author Zoltan Ujhelyi - * - */ -public interface IEMFIndexingErrorListener { - - void error(String description, Throwable t); - void fatal(String description, Throwable t); -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IQueryResultSetter.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IQueryResultSetter.java deleted file mode 100644 index 717bad4b..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IQueryResultSetter.java +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Abel Hegedus, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api; - -/** - * Setter interface for query result multimaps that allow modifications of the model through the multimap. - * - *

- * The model modifications should ensure that the multimap changes exactly as required (i.e. a put results in only one - * new key-value pair and remove results in only one removed pair). - * - *

- * The input parameters of both put and remove can be validated by implementing the {@link #validate(Object, Object)} - * method. - * - * @author Abel Hegedus - * - * @param - * @param - */ -public interface IQueryResultSetter { - /** - * Modify the underlying model of the query in order to have the given key-value pair as a new result of the query. - * - * @param key - * the key for which a new value is added to the query results - * @param value - * the new value that should be added to the query results for the given key - * @return true, if the query result changed - */ - boolean put(KeyType key, ValueType value); - - /** - * Modify the underlying model of the query in order to remove the given key-value pair from the results of the - * query. - * - * @param key - * the key for which the value is removed from the query results - * @param value - * the value that should be removed from the query results for the given key - * @return true, if the query result changed - */ - boolean remove(KeyType key, ValueType value); - - /** - * Validates a given key-value pair for the query result. The validation has to ensure that (1) if the pair does not - * exist in the result, it can be added safely (2) if the pair already exists in the result, it can be removed - * safely - * - * @param key - * the key of the pair that is validated - * @param value - * the value of the pair that is validated - * @return true, if the pair does not exists but can be added or the pair exists and can be removed - */ - boolean validate(KeyType key, ValueType value); -} \ No newline at end of file diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IQueryResultUpdateListener.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IQueryResultUpdateListener.java deleted file mode 100644 index 5addfd78..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IQueryResultUpdateListener.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Abel Hegedus, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api; - -/** - * Listener interface for receiving notification from {@link QueryResultMultimap} - * - * @author Abel Hegedus - * - * @param - * @param - */ -public interface IQueryResultUpdateListener { - /** - * This method is called by the query result multimap when a new key-value pair is put into the multimap - * - *

- * Only invoked if the contents of the multimap changed! - * - * @param key - * the key of the newly inserted pair - * @param value - * the value of the newly inserted pair - */ - void notifyPut(KeyType key, ValueType value); - - /** - * This method is called by the query result multimap when key-value pair is removed from the multimap - * - *

- * Only invoked if the contents of the multimap changed! - * - * @param key - * the key of the removed pair - * @param value - * the value of the removed pair - */ - void notifyRemove(KeyType key, ValueType value); -} \ No newline at end of file diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IStructuralFeatureInstanceProcessor.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IStructuralFeatureInstanceProcessor.java deleted file mode 100644 index 208ad761..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IStructuralFeatureInstanceProcessor.java +++ /dev/null @@ -1,19 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2017, Gabor Bergmann, IncQueryLabs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api; - -import org.eclipse.emf.ecore.EObject; - -/** - * @author Gabor Bergmann - * @since 1.7 - */ -public interface IStructuralFeatureInstanceProcessor { - void process(EObject source, Object target); -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IndexingLevel.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IndexingLevel.java deleted file mode 100644 index df5c59f5..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/IndexingLevel.java +++ /dev/null @@ -1,113 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Grill Balázs, IncQueryLabs - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api; - -import tools.refinery.viatra.runtime.matchers.context.IndexingService; - -import java.util.Set; - -/** - * The values of this enum denotes the level of indexing the base indexer is capable of. - * - * @author Grill Balázs - * @since 1.4 - * - */ -public enum IndexingLevel { - - /** - * No indexing is performed - */ - NONE, - - /** - * Only cardinality information is stored. This indexing level makes possible to calculate - * results of {@link NavigationHelper#countAllInstances(org.eclipse.emf.ecore.EClass)}, {@link NavigationHelper#countFeatures(org.eclipse.emf.ecore.EStructuralFeature)} - * and {@link NavigationHelper#countDataTypeInstances(org.eclipse.emf.ecore.EDataType)} with minimal memory footprint. - */ - STATISTICS, - - /** - * Notifications are dispatched about the changes - */ - NOTIFICATIONS, - - /** - * Cardinality information is stored and live notifications are dispatched - */ - BOTH, - - /** - * Full indexing is performed, set of instances is available - */ - FULL - - ; - - private static final IndexingLevel[][] mergeTable = { - /* NONE STATISTICS NOTIFICATIONS BOTH FULL*/ - /* NONE */{ NONE, STATISTICS, NOTIFICATIONS, BOTH, FULL}, - /* STATISTICS */{ STATISTICS, STATISTICS, BOTH, BOTH, FULL}, - /* NOTIFICATIONS */{ NOTIFICATIONS, BOTH, NOTIFICATIONS, BOTH, FULL}, - /* BOTH */{ BOTH, BOTH, BOTH, BOTH, FULL}, - /* FULL */{ FULL, FULL, FULL, FULL, FULL} - }; - - public static IndexingLevel toLevel(IndexingService service){ - switch(service){ - case INSTANCES: - return IndexingLevel.FULL; - case NOTIFICATIONS: - return IndexingLevel.NOTIFICATIONS; - case STATISTICS: - return IndexingLevel.STATISTICS; - default: - return IndexingLevel.NONE; - } - } - - public static IndexingLevel toLevel(Set services){ - IndexingLevel result = NONE; - for(IndexingService service : services){ - result = result.merge(toLevel(service)); - } - return result; - } - - /** - * Merge this level with the given other level, The resulting indexing level will provide the - * functionality which conforms to both given levels. - */ - public IndexingLevel merge(IndexingLevel other){ - if (other == null) return this; - return mergeTable[this.ordinal()][other.ordinal()]; - } - - /** - * Tells whether the indexer shall perform separate statistics calculation for this level - */ - public boolean hasStatistics() { - return this == IndexingLevel.BOTH || this == IndexingLevel.STATISTICS || this == IndexingLevel.FULL; - } - - /** - * Tells whether the indexer shall perform instance indexing - */ - public boolean hasInstances(){ - return this == IndexingLevel.FULL; - } - - /** - * Returns whether the current indexing level includes all features from the parameter level - * @since 1.5 - */ - public boolean providesLevel(IndexingLevel level) { - return this.merge(level) == this; - } -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/InstanceListener.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/InstanceListener.java deleted file mode 100644 index 6339545d..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/InstanceListener.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api; - -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EObject; - -/** - * Interface for observing insertion / deletion of instances of EClass. - * - * @author Tamas Szabo - * - */ -public interface InstanceListener { - - /** - * Called when the given instance was added to the model. - * - * @param clazz - * an EClass registered for this listener, for which a new instance (possibly an instance of a subclass) was inserted into the model - * @param instance - * an EObject instance that was inserted into the model - */ - public void instanceInserted(EClass clazz, EObject instance); - - /** - * Called when the given instance was removed from the model. - * - * @param clazz - * an EClass registered for this listener, for which an instance (possibly an instance of a subclass) was removed from the model - * @param instance - * an EObject instance that was removed from the model - */ - public void instanceDeleted(EClass clazz, EObject instance); -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/LightweightEObjectObserver.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/LightweightEObjectObserver.java deleted file mode 100644 index f0245b5d..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/LightweightEObjectObserver.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Abel Hegedus, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api; - -import org.eclipse.emf.common.notify.Notification; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EStructuralFeature; - - -/** - * Listener interface for lightweight observation on EObject feature value changes. - * - * @author Abel Hegedus - * - */ -public interface LightweightEObjectObserver { - - /** - * - * @param host - * @param feature - * @param notification - */ - void notifyFeatureChanged(EObject host, EStructuralFeature feature, Notification notification); - -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/LightweightEObjectObserverAdapter.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/LightweightEObjectObserverAdapter.java deleted file mode 100644 index bcdb8ff4..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/LightweightEObjectObserverAdapter.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Abel Hegedus, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api; - -import static tools.refinery.viatra.runtime.matchers.util.Preconditions.checkArgument; - -import java.util.Collection; -import java.util.HashSet; - -import org.eclipse.emf.common.notify.Notification; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EStructuralFeature; - -/** - * Adapter class for lightweight observer which filters feature updates to a selected set of features. - * - * @author Abel Hegedus - * - */ -public abstract class LightweightEObjectObserverAdapter implements LightweightEObjectObserver { - - private Collection observedFeatures; - - /** - * Creates a new adapter with the given set of observed features. - */ - public LightweightEObjectObserverAdapter(Collection observedFeatures) { - checkArgument(observedFeatures != null, "List of observed features must not be null!"); - this.observedFeatures = new HashSet<>(observedFeatures); - } - - public void observeAdditionalFeature(EStructuralFeature observedFeature) { - checkArgument(observedFeature != null, "Cannot observe null feature!"); - this.observedFeatures.add(observedFeature); - } - - public void observeAdditionalFeatures(Collection observedFeatures) { - checkArgument(observedFeatures != null, "List of additional observed features must not be null!"); - this.observedFeatures.addAll(observedFeatures); - } - - public void removeObservedFeature(EStructuralFeature observedFeature) { - checkArgument(observedFeature != null, "Cannot remove null observed feature!"); - this.observedFeatures.remove(observedFeature); - } - - public void removeObservedFeatures(Collection observedFeatures) { - checkArgument(observedFeatures != null, "List of observed features to remove must not be null!"); - this.observedFeatures.removeAll(observedFeatures); - } - - @Override - public void notifyFeatureChanged(EObject host, EStructuralFeature feature, Notification notification) { - if(this.observedFeatures.contains(feature)) { - observedFeatureUpdate(host, feature, notification); - } - } - - /** - * This method is called when the feature that changed is among the observed features of the adapter. - * - * @param host - * @param feature - * @param notification - */ - public abstract void observedFeatureUpdate(EObject host, EStructuralFeature feature, Notification notification); - -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/NavigationHelper.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/NavigationHelper.java deleted file mode 100644 index 6a9f704b..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/NavigationHelper.java +++ /dev/null @@ -1,885 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.base.api; - -import org.eclipse.emf.common.notify.Notifier; -import org.eclipse.emf.common.util.EList; -import org.eclipse.emf.common.util.Enumerator; -import org.eclipse.emf.ecore.*; -import org.eclipse.emf.ecore.EStructuralFeature.Setting; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; -import tools.refinery.viatra.runtime.base.api.IEClassifierProcessor.IEClassProcessor; -import tools.refinery.viatra.runtime.base.api.IEClassifierProcessor.IEDataTypeProcessor; -import tools.refinery.viatra.runtime.matchers.ViatraQueryRuntimeException; - -import java.lang.reflect.InvocationTargetException; -import java.util.Collection; -import java.util.ConcurrentModificationException; -import java.util.Set; -import java.util.concurrent.Callable; - -/** - * - * Using an index of the EMF model, this interface exposes useful query functionality, such as: - *

    - *
  • - * Getting all the (direct or descendant) instances of a given {@link EClass} - *
  • - * Inverse navigation along arbitrary {@link EReference} instances (heterogenous paths too) - *
  • - * Finding model elements by attribute value (i.e. inverse navigation along {@link EAttribute}) - *
  • - * Querying instances of given data types, or structural features. - *
- * As queries are served from an index, results are always instantaneous. - * - *

- * Such indices will be built on an EMF model rooted at an {@link EObject}, {@link Resource} or {@link ResourceSet}. - * The boundaries of the model are defined by the containment (sub)tree. - * The indices will be maintained incrementally on changes to the model; these updates can also be - * observed by registering listeners. - *

- * - *

- * One of the options is to build indices in wildcard mode, meaning that all EClasses, EDataTypes, EReferences - * and EAttributes are indexed. This is convenient, but comes at a high memory cost. To save memory, one can disable - * wildcard mode and manually register those EClasses, EDataTypes, EReferences and EAttributes that should be - * indexed. - *

- * - *

- * Another choice is whether to build indices in dynamic EMF mode, meaning that types are identified by the String IDs - * that are ultimately derived from the nsURI of the EPackage. Multiple types with the same ID are treated as the same. - * This is useful if dynamic EMF is used, where there can be multiple copies (instantiations) of the same EPackage, - * representing essentially the same metamodel. If one disables dynamic EMF mode, an error is logged if - * duplicate EPackages with the same nsURI are encountered. - *

- * - *

- * Note that none of the defined query methods return null upon empty result sets. All query methods return either a copy of - * the result sets (where {@link Setting} is instantiated) or an unmodifiable collection of the result view. - * - *

- * Instantiate using {@link ViatraBaseFactory} - * - * @author Tamas Szabo - * @noimplement This interface is not intended to be implemented by clients. - * - */ -public interface NavigationHelper { - - /** - * Indicates whether indexing is performed in wildcard mode, where every aspect of the EMF model is - * automatically indexed. - * - * @return true if everything is indexed, false if manual registration of interesting EClassifiers and - * EStructuralFeatures is required. - */ - public boolean isInWildcardMode(); - - /** - * Indicates whether indexing is performed in wildcard mode for a selected indexing level - * - * @return true if everything is indexed, false if manual registration of interesting EClassifiers and - * EStructuralFeatures is required. - * @since 1.5 - */ - public boolean isInWildcardMode(IndexingLevel level); - - /** - * Returns the current {@link IndexingLevel} applied to all model elements. For specific types it is possible to request a higher indexing levels, but cannot be lowered. - * @return the current level of index specified - * @since 1.4 - */ - public IndexingLevel getWildcardLevel(); - - /** - * Starts wildcard indexing at the given level. After this call, no registration is required for this {@link IndexingLevel}. - * a previously set wildcard level cannot be lowered, only extended. - * - * @since 1.4 - */ - public void setWildcardLevel(IndexingLevel level); - - /** - * Indicates whether indexing is performed in dynamic EMF mode, i.e. EPackage nsURI collisions are - * tolerated and EPackages with the same URI are automatically considered as equal. - * - * @return true if multiple EPackages with the same nsURI are treated as the same, - * false if an error is logged instead in this case. - */ - public boolean isInDynamicEMFMode(); - - /** - * For a given attribute value value, find each {@link EAttribute} and host {@link EObject} - * such that this attribute of the the host object takes the given value. The method will - * return a set of {@link Setting}s, one for each such host object - EAttribute - value triplet. - * - *

- * Precondition: Unset / null attribute values are not indexed, so value!=null - * - *

- * Precondition: Will only find those EAttributes that have already been registered using - * {@link #registerEStructuralFeatures(Set)}, unless running in wildcard mode (see - * {@link #isInWildcardMode()}). - * - * @param value - * the value of the attribute - * @return a set of {@link Setting}s, one for each EObject and EAttribute that have the given value - * @see #findByAttributeValue(Object) - */ - public Set findByAttributeValue(Object value); - - /** - * For given attributes and an attribute value value, find each host {@link EObject} - * such that any of these attributes of the the host object takes the given value. The method will - * return a set of {@link Setting}s, one for each such host object - EAttribute - value triplet. - * - *

- * Precondition: Unset / null attribute values are not indexed, so value!=null - * - *

- * Precondition: Will only find those EAttributes that have already been registered using - * {@link #registerEStructuralFeatures(Set)}, unless running in wildcard mode (see - * {@link #isInWildcardMode()}). - * - * @param value - * the value of the attribute - * @param attributes - * the collection of attributes that should take the given value - * @return a set of {@link Setting}s, one for each EObject and attribute that have the given value - */ - public Set findByAttributeValue(Object value, Collection attributes); - - /** - * Find all {@link EObject}s for which the given attribute takes the given value. - * - *

- * Precondition: Unset / null attribute values are not indexed, so value!=null - * - *

- * Precondition: Results will be returned only if either (a) the EAttribute has already been - * registered using {@link #registerEStructuralFeatures(Set)}, or (b) running in wildcard mode (see - * {@link #isInWildcardMode()}). - * - * @param value - * the value of the attribute - * @param attribute - * the EAttribute that should take the given value - * @return the set of {@link EObject}s for which the given attribute has the given value - */ - public Set findByAttributeValue(Object value, EAttribute attribute); - - /** - * Returns the set of instances for the given {@link EDataType} that can be found in the model. - * - *

- * Precondition: Results will be returned only if either (a) the EDataType has already been - * registered using {@link #registerEDataTypes(Set)}, or (b) running in wildcard mode (see - * {@link #isInWildcardMode()}). - * - * @param type - * the data type - * @return the set of all attribute values found in the model that are of the given data type - */ - public Set getDataTypeInstances(EDataType type); - - /** - * Returns whether an object is an instance for the given {@link EDataType} that can be found in the current scope. - *

- * Precondition: Result will be true only if either (a) the EDataType has already been registered - * using {@link #registerEDataTypes(Set)}, or (b) running in wildcard mode (see - * {@link #isInWildcardMode()}). - * - * @param value a non-null value to decide whether it is available as an EDataType instance - * @param type a non-null EDataType - * @return true, if a corresponding instance was found - * @since 1.7 - */ - public boolean isInstanceOfDatatype(Object value, EDataType type); - - /** - * Find all {@link EObject}s that are the target of the EReference reference from the given - * source {@link EObject}. - * - *

- * Unset / null-valued references are not indexed, and will not be included in the results. - * - *

- * Precondition: Results will be returned only if either (a) the reference has already been - * registered using {@link #registerEStructuralFeatures(Set)}, or (b) running in wildcard mode (see - * {@link #isInWildcardMode()}). - * - * @param source the host object - * @param reference an EReference of the host object - * @return the set of {@link EObject}s that the given reference points to, from the given source object - */ - public Set getReferenceValues(EObject source, EReference reference); - - /** - * Find all {@link Object}s that are the target of the EStructuralFeature feature from the given - * source {@link EObject}. - * - *

- * Unset / null-valued features are not indexed, and will not be included in the results. - * - *

- * Precondition: Results will be returned only if either (a) the feature has already been - * registered, or (b) running in wildcard mode (see - * {@link #isInWildcardMode()}). - * - * @param source the host object - * @param feature an EStructuralFeature of the host object - * @return the set of values that the given feature takes at the given source object - * - * @see #getReferenceValues(EObject, EReference) - */ - public Set getFeatureTargets(EObject source, EStructuralFeature feature); - - /** - * Decides whether the given non-null source and target objects are connected via a specific, indexed EStructuralFeature instance. - * - *

- * Unset / null-valued features are not indexed, and will not be included in the results. - * - *

- * Precondition: Result will be true only if either (a) the feature has already been - * registered, or (b) running in wildcard mode (see - * {@link #isInWildcardMode()}). - * @since 1.7 - */ - public boolean isFeatureInstance(EObject source, Object target, EStructuralFeature feature); - - /** - * For a given {@link EObject} target, find each {@link EReference} and source {@link EObject} - * such that this reference (list) of the the host object points to the given target object. The method will - * return a set of {@link Setting}s, one for each such source object - EReference - target triplet. - * - *

- * Precondition: Unset / null reference values are not indexed, so target!=null - * - *

- * Precondition: Results will be returned only for those references that have already been - * registered using {@link #registerEStructuralFeatures(Set)}, or all references if running in - * wildcard mode (see {@link #isInWildcardMode()}). - * - * @param target - * the EObject pointed to by the references - * @return a set of {@link Setting}s, one for each source EObject and reference that point to the given target - */ - public Set getInverseReferences(EObject target); - - /** - * For given references and an {@link EObject} target, find each source {@link EObject} - * such that any of these references of the the source object points to the given target object. The method will - * return a set of {@link Setting}s, one for each such source object - EReference - target triplet. - * - *

- * Precondition: Unset / null reference values are not indexed, so target!=null - * - *

- * Precondition: Will only find those EReferences that have already been registered using - * {@link #registerEStructuralFeatures(Set)}, unless running in wildcard mode (see - * {@link #isInWildcardMode()}). - * - * @param target - * the EObject pointed to by the references - * @param references a set of EReferences pointing to the target - * @return a set of {@link Setting}s, one for each source EObject and reference that point to the given target - */ - public Set getInverseReferences(EObject target, Collection references); - - /** - * Find all source {@link EObject}s for which the given reference points to the given target object. - * - *

- * Precondition: Unset / null reference values are not indexed, so target!=null - * - *

- * Precondition: Results will be returned only if either (a) the reference has already been - * registered using {@link #registerEStructuralFeatures(Set)}, or (b) running in wildcard mode (see - * {@link #isInWildcardMode()}). - * - * @param target - * the EObject pointed to by the references - * @param reference - * an EReference pointing to the target - * @return the collection of {@link EObject}s for which the given reference points to the given target object - */ - public Set getInverseReferences(EObject target, EReference reference); - - /** - * Get the direct {@link EObject} instances of the given {@link EClass}. Instances of subclasses will be excluded. - * - *

- * Precondition: Results will be returned only if either (a) the EClass (or any superclass) has - * already been registered using {@link #registerEClasses(Set)}, or (b) running in wildcard mode (see - * {@link #isInWildcardMode()}). - * - * @param clazz - * an EClass - * @return the collection of {@link EObject} direct instances of the given EClass (not of subclasses) - * - * @see #getAllInstances(EClass) - */ - public Set getDirectInstances(EClass clazz); - - /** - * Get the all {@link EObject} instances of the given {@link EClass}. - * This includes instances of subclasses. - * - *

- * Precondition: Results will be returned only if either (a) the EClass (or any superclass) has - * already been registered using {@link #registerEClasses(Set)}, or (b) running in wildcard mode (see - * {@link #isInWildcardMode()}). - * - * @param clazz - * an EClass - * @return the collection of {@link EObject} instances of the given EClass and any of its subclasses - * - * @see #getDirectInstances(EClass) - */ - public Set getAllInstances(EClass clazz); - - /** - * Checks whether the given {@link EObject} is an instance of the given {@link EClass}. - * This includes instances of subclasses. - *

Special note: this method does not check whether the object is indexed in the scope, - * and will return true for out-of-scope objects as well (as long as they are instances of the class). - *

The given class does not have to be indexed. - *

The difference between this method and {@link EClassifier#isInstance(Object)} is that in dynamic EMF mode, EPackage equivalence is taken into account. - * @since 1.6 - */ - public boolean isInstanceOfUnscoped(EObject object, EClass clazz); - - /** - * Checks whether the given {@link EObject} is an instance of the given {@link EClass}. - * This includes instances of subclasses. - *

Special note: this method does check whether the object is indexed in the scope, - * and will return false for out-of-scope objects as well (as long as they are instances of the class). - *

The given class does have to be indexed. - * @since 1.7 - */ - public boolean isInstanceOfScoped(EObject object, EClass clazz); - - /** - * Get the total number of instances of the given {@link EClass} and all of its subclasses. - * - * @since 1.4 - */ - public int countAllInstances(EClass clazz); - - /** - * Find all source {@link EObject}s for which the given feature points to / takes the given value. - * - *

- * Precondition: Unset / null-valued features are not indexed, so value!=null - * - *

- * Precondition: Results will be returned only if either (a) the feature has already been - * registered using {@link #registerEStructuralFeatures(Set)}, or (b) running in wildcard mode (see - * {@link #isInWildcardMode()}). - * - * @param value - * the value of the feature - * @param feature - * the feature instance - * @return the collection of {@link EObject} instances - */ - public Set findByFeatureValue(Object value, EStructuralFeature feature); - - /** - * Returns those host {@link EObject}s that have a non-null value for the given feature - * (at least one, in case of multi-valued references). - * - *

- * Unset / null-valued features are not indexed, and will not be included in the results. - * - *

- * Precondition: Results will be returned only if either (a) the feature has already been - * registered using {@link #registerEStructuralFeatures(Set)}, or (b) running in wildcard mode (see - * {@link #isInWildcardMode()}). - * - * @param feature - * a structural feature - * @return the collection of {@link EObject}s that have some value for the given structural feature - */ - public Set getHoldersOfFeature(EStructuralFeature feature); - /** - * Returns all non-null values that the given feature takes at least once for any {@link EObject} in the scope - * - *

- * Unset / null-valued features are not indexed, and will not be included in the results. - * - *

- * Precondition: Results will be returned only if either (a) the feature has already been - * registered using {@link #registerEStructuralFeatures(Set)}, or (b) running in wildcard mode (see - * {@link #isInWildcardMode()}). - * - * @param feature - * a structural feature - * @return the collection of values that the given structural feature takes - * @since 2.1 - */ - public Set getValuesOfFeature(EStructuralFeature feature); - - /** - * Call this method to dispose the NavigationHelper. - * - *

After its disposal, the NavigationHelper will no longer listen to EMF change notifications, - * and it will be possible to GC it even if the model is retained in memory. - * - *

Precondition:
no listeners can be registered at all. - * @throws IllegalStateException if there are any active listeners - * - */ - public void dispose(); - - /** - * The given listener will be notified from now on whenever instances the given {@link EClass}es - * (and any of their subtypes) are added to or removed from the model. - * - *
- * Important: Do not call this method from {@link InstanceListener} methods as it may cause a - * {@link ConcurrentModificationException}, if you want to add a listener - * at that point, wrap the call with {@link #executeAfterTraversal(Runnable)}. - * - * @param classes - * the collection of classes whose instances the listener should be notified of - * @param listener - * the listener instance - */ - public void addInstanceListener(Collection classes, InstanceListener listener); - - /** - * Unregisters an instance listener for the given classes. - * - *
- * Important: Do not call this method from {@link InstanceListener} methods as it may cause a - * {@link ConcurrentModificationException}, if you want to remove a listener at that point, wrap the call with - * {@link #executeAfterTraversal(Runnable)}. - * - * @param classes - * the collection of classes - * @param listener - * the listener instance - */ - public void removeInstanceListener(Collection classes, InstanceListener listener); - - /** - * The given listener will be notified from now on whenever instances the given {@link EDataType}s are - * added to or removed from the model. - * - *
- * Important: Do not call this method from {@link DataTypeListener} methods as it may cause a - * {@link ConcurrentModificationException}, if you want to add a listener at that point, wrap the call with - * {@link #executeAfterTraversal(Runnable)}. - * - * @param types - * the collection of types associated to the listener - * @param listener - * the listener instance - */ - public void addDataTypeListener(Collection types, DataTypeListener listener); - - /** - * Unregisters a data type listener for the given types. - * - *
- * Important: Do not call this method from {@link DataTypeListener} methods as it may cause a - * {@link ConcurrentModificationException}, if you want to remove a listener at that point, wrap the call with - * {@link #executeAfterTraversal(Runnable)}. - * - * @param types - * the collection of data types - * @param listener - * the listener instance - */ - public void removeDataTypeListener(Collection types, DataTypeListener listener); - - /** - * The given listener will be notified from now on whenever instances the given - * {@link EStructuralFeature}s are added to or removed from the model. - * - *
- * Important: Do not call this method from {@link FeatureListener} methods as it may cause a - * {@link ConcurrentModificationException}, if you want to add a listener at that point, wrap the call with - * {@link #executeAfterTraversal(Runnable)}. - * - * @param features - * the collection of features associated to the listener - * @param listener - * the listener instance - */ - public void addFeatureListener(Collection features, FeatureListener listener); - - /** - * Unregisters a feature listener for the given features. - * - *
- * Important: Do not call this method from {@link FeatureListener} methods as it may cause a - * {@link ConcurrentModificationException}, if you want to remove a listener at that point, wrap the call with - * {@link #executeAfterTraversal(Runnable)}. - * - * @param listener - * the listener instance - * @param features - * the collection of features - */ - public void removeFeatureListener(Collection features, FeatureListener listener); - - /** - * Register a lightweight observer that is notified if the value of any feature of the given EObject changes. - * - *
- * Important: Do not call this method from {@link LightweightEObjectObserver} methods as it may cause a - * {@link ConcurrentModificationException}, if you want to add an observer at that point, wrap the call with - * {@link #executeAfterTraversal(Runnable)}. - * - * @param observer - * the listener instance - * @param observedObject - * the observed EObject - * @return false if the observer was already attached to the object (call has no effect), true otherwise - */ - public boolean addLightweightEObjectObserver(LightweightEObjectObserver observer, EObject observedObject); - - /** - * Unregisters a lightweight observer for the given EObject. - * - *
- * Important: Do not call this method from {@link LightweightEObjectObserver} methods as it may cause a - * {@link ConcurrentModificationException}, if you want to remove an observer at that point, wrap the call with - * {@link #executeAfterTraversal(Runnable)}. - * - * @param observer - * the listener instance - * @param observedObject - * the observed EObject - * @return false if the observer has not been previously attached to the object (call has no effect), true otherwise - */ - public boolean removeLightweightEObjectObserver(LightweightEObjectObserver observer, EObject observedObject); - - /** - * Manually turns on indexing for the given types (indexing of others are unaffected). Note that - * registering new types will result in a single iteration through the whole attached model. - * Not usable in wildcard mode. - * - * @param classes - * the set of classes to observe (null okay) - * @param dataTypes - * the set of data types to observe (null okay) - * @param features - * the set of features to observe (null okay) - * @throws IllegalStateException if in wildcard mode - * @since 1.4 - */ - public void registerObservedTypes(Set classes, Set dataTypes, Set features, IndexingLevel level); - - /** - * Manually turns off indexing for the given types (indexing of others are unaffected). Note that if the - * unregistered types are re-registered later, the whole attached model needs to be visited again. - * Not usable in wildcard mode. - * - *
Precondition:
no listeners can be registered for the given types. - * @param classes - * the set of classes that will be ignored again from now on (null okay) - * @param dataTypes - * the set of data types that will be ignored again from now on (null okay) - * @param features - * the set of features that will be ignored again from now on (null okay) - * @throws IllegalStateException if in wildcard mode, or if there are listeners registered for the given types - */ - public void unregisterObservedTypes(Set classes, Set dataTypes, Set features); - - /** - * Manually turns on indexing for the given features (indexing of other features are unaffected). Note that - * registering new features will result in a single iteration through the whole attached model. - * Not usable in wildcard mode. - * - * @param features - * the set of features to observe - * @throws IllegalStateException if in wildcard mode - * @since 1.4 - */ - public void registerEStructuralFeatures(Set features, IndexingLevel level); - - /** - * Manually turns off indexing for the given features (indexing of other features are unaffected). Note that if the - * unregistered features are re-registered later, the whole attached model needs to be visited again. - * Not usable in wildcard mode. - * - *
Precondition:
no listeners can be registered for the given features. - * - * @param features - * the set of features that will be ignored again from now on - * @throws IllegalStateException if in wildcard mode, or if there are listeners registered for the given types - */ - public void unregisterEStructuralFeatures(Set features); - - /** - * Manually turns on indexing for the given classes (indexing of other classes are unaffected). Instances of - * subclasses will also be indexed. Note that registering new classes will result in a single iteration through the whole - * attached model. - * Not usable in wildcard mode. - * - * @param classes - * the set of classes to observe - * @throws IllegalStateException if in wildcard mode - * @since 1.4 - */ - public void registerEClasses(Set classes, IndexingLevel level); - - /** - * Manually turns off indexing for the given classes (indexing of other classes are unaffected). Note that if the - * unregistered classes are re-registered later, the whole attached model needs to be visited again. - * Not usable in wildcard mode. - * - *
Precondition:
no listeners can be registered for the given classes. - * @param classes - * the set of classes that will be ignored again from now on - * @throws IllegalStateException if in wildcard mode, or if there are listeners registered for the given types - */ - public void unregisterEClasses(Set classes); - - /** - * Manually turns on indexing for the given data types (indexing of other features are unaffected). Note that - * registering new data types will result in a single iteration through the whole attached model. - * Not usable in wildcard mode. - * - * @param dataTypes - * the set of data types to observe - * @throws IllegalStateException if in wildcard mode - * @since 1.4 - */ - public void registerEDataTypes(Set dataTypes, IndexingLevel level); - - /** - * Manually turns off indexing for the given data types (indexing of other data types are unaffected). Note that if - * the unregistered data types are re-registered later, the whole attached model needs to be visited again. - * Not usable in wildcard mode. - * - *
Precondition:
no listeners can be registered for the given datatypes. - * - * @param dataTypes - * the set of data types that will be ignored again from now on - * @throws IllegalStateException if in wildcard mode, or if there are listeners registered for the given types - */ - public void unregisterEDataTypes(Set dataTypes); - - /** - * The given callback will be executed, and all model traversals and index registrations will be delayed until the - * execution is done. If there are any outstanding feature, class or datatype registrations, a single coalesced model - * traversal will initialize the caches and deliver the notifications. - * - * @param callable - */ - public V coalesceTraversals(Callable callable) throws InvocationTargetException; - - /** - * Execute the given runnable after traversal. It is guaranteed that the runnable is executed as soon as - * the indexing is finished. The callback is executed only once, then is removed from the callback queue. - * @param traversalCallback - * @throws InvocationTargetException - * @since 1.4 - */ - public void executeAfterTraversal(Runnable traversalCallback) throws InvocationTargetException; - - /** - * Examines whether execution is currently in the callable - * block of an invocation of {#link {@link #coalesceTraversals(Callable)}}. - */ - public boolean isCoalescing(); - - /** - * Adds a coarse-grained listener that will be invoked after the NavigationHelper index or the underlying model is changed. Can be used - * e.g. to check model contents. Not intended for general use. - * - *

See {@link #removeBaseIndexChangeListener(EMFBaseIndexChangeListener)} - * @param listener - */ - public void addBaseIndexChangeListener(EMFBaseIndexChangeListener listener); - - /** - * Removes a registered listener. - * - *

See {@link #addBaseIndexChangeListener(EMFBaseIndexChangeListener)} - * - * @param listener - */ - public void removeBaseIndexChangeListener(EMFBaseIndexChangeListener listener); - - /** - * Adds an additional EMF model root. - * - * @param emfRoot - * @throws ViatraQueryRuntimeException - */ - public void addRoot(Notifier emfRoot); - - /** - * Moves an EObject (along with its entire containment subtree) within the containment hierarchy of the EMF model. - * The object will be relocated from the original parent object to a different parent, or a different containment - * list of the same parent. - * - *

When indexing is enabled, such a relocation is costly if performed through normal getters/setters, as the index - * for the entire subtree is pruned at the old location and reconstructed at the new one. - * This method provides a workaround to keep the operation cheap. - * - *

This method is experimental. Re-entrancy not supported. - * - * @param element the eObject to be moved - * @param targetContainmentReferenceList containment list of the new parent object into which the element has to be moved - * - */ - public void cheapMoveTo(T element, EList targetContainmentReferenceList); - - /** - * Moves an EObject (along with its entire containment subtree) within the containment hierarchy of the EMF model. - * The object will be relocated from the original parent object to a different parent, or a different containment - * list of the same parent. - * - *

When indexing is enabled, such a relocation is costly if performed through normal getters/setters, as the index - * for the entire subtree is pruned at the old location and reconstructed at the new one. - * This method provides a workaround to keep the operation cheap. - * - *

This method is experimental. Re-entrancy not supported. - * - * @param element the eObject to be moved - * @param parent the new parent object under which the element has to be moved - * @param containmentFeature the kind of containment reference that should be established between the new parent and the element - * - */ - public void cheapMoveTo(EObject element, EObject parent, EReference containmentFeature); - - - /** - * Traverses all instances of a selected data type stored in the base index, and allows executing a custom function on - * it. There is no guaranteed order in which the processor will be called with the selected features. - * - * @param type - * @param processor - * @since 0.8 - */ - void processDataTypeInstances(EDataType type, IEDataTypeProcessor processor); - - /** - * Traverses all direct instances of a selected class stored in the base index, and allows executing a custom function on - * it. There is no guaranteed order in which the processor will be called with the selected features. - * - * @param type - * @param processor - * @since 0.8 - */ - void processAllInstances(EClass type, IEClassProcessor processor); - - /** - * Traverses all direct instances of a selected class stored in the base index, and allows executing a custom function on - * it. There is no guaranteed order in which the processor will be called with the selected features. - * - * @param type - * @param processor - * @since 0.8 - */ - void processDirectInstances(EClass type, IEClassProcessor processor); - - /** - * Traverses all instances of a selected feature stored in the base index, and allows executing a custom function on - * it. There is no guaranteed order in which the processor will be called with the selected features. - * - *

- * Precondition: Will only find those {@link EStructuralFeature}s that have already been registered using - * {@link #registerEStructuralFeatures(Set)}, unless running in wildcard mode (see - * {@link #isInWildcardMode()}). - * - * @since 1.7 - */ - void processAllFeatureInstances(EStructuralFeature feature, IStructuralFeatureInstanceProcessor processor); - /** - * Returns all EClasses that currently have direct instances cached by the index.

    - *
  • Supertypes will not be returned, unless they have direct instances in the model as well. - *
  • If not in wildcard mode, only registered EClasses and their subtypes will be considered. - *
  • Note for advanced users: if a type is represented by multiple EClass objects, one of them is chosen as representative and returned. - *
- */ - public Set getAllCurrentClasses(); - - /** - * Updates the value of indexed derived features that are not well-behaving. - */ - void resampleDerivedFeatures(); - - /** - * Adds a listener for internal errors in the index. A listener can only be added once. - * - * @param listener - * @returns true if the listener was not already added - * @since 0.8 - */ - boolean addIndexingErrorListener(IEMFIndexingErrorListener listener); - - /** - * Removes a listener for internal errors in the index. - * - * @param listener - * @returns true if the listener was successfully removed (e.g. it did exist) - * @since 0.8 - */ - boolean removeIndexingErrorListener(IEMFIndexingErrorListener listener); - - /** - * Returns the internal, canonicalized implementation of an attribute value. - * - *

Behaviour: when in dynamic EMF mode, substitutes enum literals with a canonical version of the enum literal. - * Otherwise, returns the input. - * - *

The canonical enum literal will be guaranteed to be a valid EMF enum literal ({@link Enumerator}), - * and the best effort is made to ensure that it will be the same for all versions of the {@link EEnum}, - * including {@link EEnumLiteral}s in different versions of ecore packages, as well as Java enums generated from them.. - * - *

Usage is not required when simply querying the indexed model through the {@link NavigationHelper} API, - * as both method inputs and the results returned are automatically canonicalized in dynamic EMF mode. - * Using this method is required only if the client wants to do querying/filtering on the results returned, and wants to know what to look for. - */ - Object toCanonicalValueRepresentation(Object value); - - /** - * @since 1.4 - */ - IndexingLevel getIndexingLevel(EClass type); - - /** - * @since 1.4 - */ - IndexingLevel getIndexingLevel(EDataType type); - - /** - * @since 1.4 - */ - IndexingLevel getIndexingLevel(EStructuralFeature feature); - - /** - * @since 1.4 - */ - public int countDataTypeInstances(EDataType dataType); - - /** - * @since 1.4 - */ - public int countFeatureTargets(EObject seedSource, EStructuralFeature feature); - - /** - * @since 1.4 - */ - public int countFeatures(EStructuralFeature feature); - - -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/QueryResultAssociativeStore.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/QueryResultAssociativeStore.java deleted file mode 100644 index 27d08506..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/QueryResultAssociativeStore.java +++ /dev/null @@ -1,322 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Abel Hegedus, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map.Entry; - -import org.apache.log4j.Logger; -import tools.refinery.viatra.runtime.matchers.util.Direction; - -/** - * @author Abel Hegedus - * - */ -public abstract class QueryResultAssociativeStore { - /** - * Error literal returned when associative store modification is attempted without a setter available - */ - protected static final String NOT_ALLOW_MODIFICATIONS = "Query result associative store does not allow modifications"; - - /** - * Logger that can be used for reporting errors during runtime - */ - private Logger logger; - /** - * The collection of listeners registered for this result associative store - */ - private Collection> listeners; - - /** - * The setter registered for changing the contents of the associative store - */ - private IQueryResultSetter setter; - - /** - * @return the listeners - */ - protected Collection> getListeners() { - return listeners; - } - - /** - * @param listeners the listeners to set - */ - protected void setListeners(Collection> listeners) { - this.listeners = listeners; - } - - /** - * @return the setter - */ - protected IQueryResultSetter getSetter() { - return setter; - } - - /** - * @param setter the setter to set - */ - protected void setSetter(IQueryResultSetter setter) { - this.setter = setter; - } - - /** - * @param logger the logger to set - */ - protected void setLogger(Logger logger) { - this.logger = logger; - } - - /** - * Returns the entries in the cache as a collection. - * @return the entries - */ - protected abstract Collection> getCacheEntries(); - - /** - * Registers a listener for this query result associative store that is invoked every time when a key-value pair is inserted - * or removed from the associative store. - * - *

- * The listener can be unregistered via {@link #removeCallbackOnQueryResultUpdate(IQueryResultUpdateListener)}. - * - * @param listener - * the listener that will be notified of each key-value pair that is inserted or removed, starting from - * now. - * @param fireNow - * if true, notifyPut will be immediately invoked on all current key-values as a one-time effect. - */ - public void addCallbackOnQueryResultUpdate(IQueryResultUpdateListener listener, boolean fireNow) { - if (listeners == null) { - listeners = new HashSet>(); - } - listeners.add(listener); - if(fireNow) { - for (Entry entry : getCacheEntries()) { - sendNotificationToListener(Direction.INSERT, entry.getKey(), entry.getValue(), listener); - } - } - } - - /** - * Unregisters a callback registered by {@link #addCallbackOnQueryResultUpdate(IQueryResultUpdateListener, boolean)} - * . - * - * @param listener - * the listener that will no longer be notified. - */ - public void removeCallbackOnQueryResultUpdate(IQueryResultUpdateListener listener) { - if (listeners != null) { - listeners.remove(listener); - } - } - - /** - * This method notifies the listeners that the query result associative store has changed. - * - * @param direction - * the type of the change (insert or delete) - * @param key - * the key of the pair that changed - * @param value - * the value of the pair that changed - */ - protected void notifyListeners(Direction direction, KeyType key, ValueType value) { - if(listeners != null) { - for (IQueryResultUpdateListener listener : listeners) { - sendNotificationToListener(direction, key, value, listener); - } - } - } - - private void sendNotificationToListener(Direction direction, KeyType key, ValueType value, - IQueryResultUpdateListener listener) { - try { - if (direction == Direction.INSERT) { - listener.notifyPut(key, value); - } else { - listener.notifyRemove(key, value); - } - } catch (Exception e) { // NOPMD - logger.warn( - String.format( - "The query result associative store encountered an error during executing a callback on %s of key %s and value %s. Error message: %s. (Developer note: %s in %s called from QueryResultMultimap)", - direction == Direction.INSERT ? "insertion" : "removal", key, value, e.getMessage(), e - .getClass().getSimpleName(), listener), e); - throw new IllegalStateException("The query result associative store encountered an error during invoking setter",e); - } - } - - /** - * Implementations of QueryResultAssociativeStore can put a new key-value pair into the associative store with this method. If the - * insertion of the key-value pair results in a change, the listeners are notified. - * - *

- * No validation or null-checking is performed during the method! - * - * @param key - * the key which identifies where the new value is put - * @param value - * the value that is put into the collection of the key - * @return true, if the insertion resulted in a change (the key-value pair was not yet in the associative store) - */ - protected boolean internalPut(KeyType key, ValueType value){ - boolean putResult = internalCachePut(key, value); - if (putResult) { - notifyListeners(Direction.INSERT, key, value); - } - return putResult; - } - /** - * Implementations of QueryResultAssociativeStore can remove a key-value pair from the associative store with this method. If the - * removal of the key-value pair results in a change, the listeners are notified. - * - *

- * No validation or null-checking is performed during the method! - * - * @param key - * the key which identifies where the value is removed from - * @param value - * the value that is removed from the collection of the key - * @return true, if the removal resulted in a change (the key-value pair was in the associative store) - */ - protected boolean internalRemove(KeyType key, ValueType value){ - boolean removeResult = internalCacheRemove(key, value); - if (removeResult) { - notifyListeners(Direction.DELETE, key, value); - } - return removeResult; - } - - - protected abstract boolean internalCachePut(KeyType key, ValueType value); - protected abstract boolean internalCacheRemove(KeyType key, ValueType value); - protected abstract int internalCacheSize(); - protected abstract boolean internalCacheContainsEntry(KeyType key, ValueType value); - - /** - * @param setter - * the setter to set - */ - public void setQueryResultSetter(IQueryResultSetter setter) { - this.setter = setter; - } - - /** - * @return the logger - */ - protected Logger getLogger() { - return logger; - } - - protected void internalClear() { - if (setter == null) { - throw new UnsupportedOperationException(NOT_ALLOW_MODIFICATIONS); - } - Collection> entries = new ArrayList<>(getCacheEntries()); - Iterator> iterator = entries.iterator(); - while (iterator.hasNext()) { - Entry entry = iterator.next(); - modifyThroughQueryResultSetter(entry.getKey(), entry.getValue(), Direction.DELETE); - } - if (internalCacheSize() != 0) { - StringBuilder sb = new StringBuilder(); - for (Entry entry : getCacheEntries()) { - if (sb.length() > 0) { - sb.append(", "); - } - sb.append(entry.toString()); - } - logger.warn(String - .format("The query result associative store is not empty after clear, remaining entries: %s. (Developer note: %s called from QueryResultMultimap)", - sb.toString(), setter)); - } - } - - /** - * This method is used for calling the query result setter to put or remove a value by modifying the model. - * - *

- * The given key-value pair is first validated (see {@link IQueryResultSetter#validate(Object, Object)}, then the - * put or remove method is called (see {@link IQueryResultSetter#put(Object, Object)} and - * {@link IQueryResultSetter#remove(Object, Object)}). If the setter reported that the model has been changed, the - * change is checked. - * - *

- * If the model modification did not change the result set in the desired way, a warning is logged. - * - *

- * If the setter throws any {@link Throwable}, it is either rethrown in case of {@link Error} and logged otherwise. - * - * - * @param key - * the key of the pair to be inserted or removed - * @param value - * the value of the pair to be inserted or removed - * @param direction - * specifies whether a put or a remove is performed - * @return true, if the associative store changed according to the direction - */ - protected boolean modifyThroughQueryResultSetter(KeyType key, ValueType value, Direction direction) { - try { - if (setter.validate(key, value)) { - final int size = internalCacheSize(); - final int expectedChange = (direction == Direction.INSERT) ? 1 : -1; - boolean changed = false; - if (direction == Direction.INSERT) { - changed = setter.put(key, value); - } else { - changed = setter.remove(key, value); - } - if (changed) { - return checkModificationThroughQueryResultSetter(key, value, direction, expectedChange, size); - } else { - logger.warn(String - .format("The query result associative store %s of key %s and value %s resulted in %s. (Developer note: %s called from QueryResultMultimap)", - direction == Direction.INSERT ? "insertion" : "removal", key, value, - Math.abs(internalCacheSize() - size) > 1 ? "more than one changed result" - : "no changed results", setter)); - } - } - } catch (Exception e) { // NOPMD - logger.warn( - String.format( - "The query result associative store encountered an error during invoking setter on %s of key %s and value %s. Error message: %s. (Developer note: %s in %s called from QueryResultMultimap)", - direction == Direction.INSERT ? "insertion" : "removal", key, value, e.getMessage(), e - .getClass().getSimpleName(), setter), e); - throw new IllegalStateException("The query result associative store encountered an error during invoking setter",e); - } - - return false; - } - - /** - * Checks whether the model modification performed by the {@link IQueryResultSetter} resulted in the insertion or - * removal of exactly the required key-value pair. - * - * @param key - * the key for the pair that was inserted or removed - * @param value - * the value for the pair that was inserted or removed - * @param direction - * the direction of the change - * @param size - * the size of the cache before the change - * @return true, if the changes made by the query result setter were correct - */ - protected boolean checkModificationThroughQueryResultSetter(KeyType key, ValueType value, Direction direction, - final int expectedChange, final int size) { - boolean isInsertion = direction == Direction.INSERT; - return (isInsertion == internalCacheContainsEntry(key, value) - && (internalCacheSize() - expectedChange) == size); - } -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/QueryResultMap.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/QueryResultMap.java deleted file mode 100644 index a106ea71..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/QueryResultMap.java +++ /dev/null @@ -1,210 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Abel Hegedus, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.apache.log4j.Logger; -import tools.refinery.viatra.runtime.matchers.util.Direction; - -/** - * @author Abel Hegedus - * - */ -public abstract class QueryResultMap extends QueryResultAssociativeStore implements Map { - - /** - * This map contains the current key-values. Implementing classes should not modify it directly - */ - private Map cache; - - /** - * Constructor only visible to subclasses. - * - * @param logger - * a logger that can be used for error reporting - */ - protected QueryResultMap(Logger logger) { - cache = new HashMap(); - setLogger(logger); - } - - @Override - protected Collection> getCacheEntries() { - return cache.entrySet(); - } - - @Override - protected boolean internalCachePut(KeyType key, ValueType value) { - ValueType put = cache.put(key, value); - if(put == null) { - return value != null; - } else { - return !put.equals(value); - } - } - - @Override - protected boolean internalCacheRemove(KeyType key, ValueType value) { - ValueType remove = cache.remove(key); - return remove != null; - } - - @Override - protected int internalCacheSize() { - return cache.size(); - } - - @Override - protected boolean internalCacheContainsEntry(KeyType key, ValueType value) { - return cache.containsKey(key) && cache.get(key).equals(value); - } - - /** - * @return the cache - */ - protected Map getCache() { - return cache; - } - - /** - * @param cache - * the cache to set - */ - protected void setCache(Map cache) { - this.cache = cache; - } - - // ======================= implemented Map methods ====================== - - @Override - public void clear() { - internalClear(); - } - - @Override - public boolean containsKey(Object key) { - return cache.containsKey(key); - } - - @Override - public boolean containsValue(Object value) { - return cache.containsValue(value); - } - - /** - * {@inheritDoc} - * - *

- * The returned set is immutable. - * - */ - @Override - public Set> entrySet() { - return Collections.unmodifiableSet((Set>) getCacheEntries()); - } - - @Override - public ValueType get(Object key) { - return cache.get(key); - } - - @Override - public boolean isEmpty() { - return cache.isEmpty(); - } - - /** - * {@inheritDoc} - * - *

- * The returned set is immutable. - * - */ - @Override - public Set keySet() { - return Collections.unmodifiableSet(cache.keySet()); - } - - /** - * {@inheritDoc} - * - *

- * Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} - */ - @Override - public ValueType put(KeyType key, ValueType value) { - if (getSetter() == null) { - throw new UnsupportedOperationException(NOT_ALLOW_MODIFICATIONS); - } - ValueType oldValue = cache.get(key); - boolean modified = modifyThroughQueryResultSetter(key, value, Direction.INSERT); - return modified ? oldValue : null; - } - - /** - * {@inheritDoc} - * - *

- * Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} - */ - @Override - public void putAll(Map map) { - if (getSetter() == null) { - throw new UnsupportedOperationException(NOT_ALLOW_MODIFICATIONS); - } - for (Entry entry : map.entrySet()) { - modifyThroughQueryResultSetter(entry.getKey(), entry.getValue(), Direction.INSERT); - } - return; - } - - /** - * {@inheritDoc} - * - *

- * Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter} - */ - @SuppressWarnings("unchecked") - @Override - public ValueType remove(Object key) { - if (getSetter() == null) { - throw new UnsupportedOperationException(NOT_ALLOW_MODIFICATIONS); - } - // if it contains the entry, the types MUST be correct - if (cache.containsKey(key)) { - ValueType value = cache.get(key); - modifyThroughQueryResultSetter((KeyType) key, value, Direction.DELETE); - return value; - } - return null; - } - - @Override - public int size() { - return internalCacheSize(); - } - - /** - * {@inheritDoc} - * - *

- * The returned collection is immutable. - * - */ - @Override - public Collection values() { - return Collections.unmodifiableCollection(cache.values()); - } - -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/TransitiveClosureHelper.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/TransitiveClosureHelper.java deleted file mode 100644 index fc92fef3..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/TransitiveClosureHelper.java +++ /dev/null @@ -1,26 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.base.api; - -import org.eclipse.emf.ecore.EObject; -import tools.refinery.viatra.runtime.base.itc.igraph.ITcDataSource; - -/** - * The class can be used to compute the transitive closure of a given emf model, where the nodes will be the objects in - * the model and the edges will be represented by the references between them. One must provide the set of references - * that the helper should treat as edges when creating an instance with the factory: only the notifications about these - * references will be handled. - * - * @author Tamas Szabo - * - */ -public interface TransitiveClosureHelper extends ITcDataSource { - -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/ViatraBaseFactory.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/ViatraBaseFactory.java deleted file mode 100644 index 81bd4f35..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/ViatraBaseFactory.java +++ /dev/null @@ -1,180 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.base.api; - -import java.util.Set; - -import org.apache.log4j.Logger; -import org.eclipse.emf.common.notify.Notifier; -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EDataType; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.base.core.NavigationHelperImpl; -import tools.refinery.viatra.runtime.base.core.TransitiveClosureHelperImpl; - -/** - * Factory class for the utils in the library:

    - *
  • NavigationHelper (automatic and manual) - *
  • TransitiveClosureUtil - *
- * - * @author Tamas Szabo - * - */ -public class ViatraBaseFactory { - - private static ViatraBaseFactory instance; - - /** - * Get the singleton instance of ViatraBaseFactory. - * - * @return the singleton instance - */ - public static synchronized ViatraBaseFactory getInstance() { - if (instance == null) { - instance = new ViatraBaseFactory(); - } - - return instance; - } - - protected ViatraBaseFactory() { - super(); - } - - /** - * The method creates a {@link NavigationHelper} index for the given EMF model root. - * A new instance will be created on every call. - *

- * A NavigationHelper in wildcard mode will process and index all EStructuralFeatures, EClasses and EDatatypes. If - * wildcard mode is off, the client will have to manually register the interesting aspects of the model. - *

- * The NavigationHelper will be created without dynamic EMF support by default. - * See {@link #createNavigationHelper(Notifier, boolean, boolean, Logger)} for more options. - * - * @see NavigationHelper - * - * @param emfRoot - * the root of the EMF tree to be indexed. Recommended: Resource or ResourceSet. Can be null - you can - * add a root later using {@link NavigationHelper#addRoot(Notifier)} - * @param wildcardMode - * true if all aspects of the EMF model should be indexed automatically, false if manual registration of - * interesting aspects is desirable - * @param logger - * the log output where errors will be logged if encountered during the operation of the - * NavigationHelper; if null, the default logger for {@link NavigationHelper} is used. - * @return the NavigationHelper instance - * @throws ViatraQueryRuntimeException - */ - public NavigationHelper createNavigationHelper(Notifier emfRoot, boolean wildcardMode, Logger logger) { - BaseIndexOptions options = new BaseIndexOptions(false, wildcardMode ? IndexingLevel.FULL : IndexingLevel.NONE); - return createNavigationHelper(emfRoot, options, logger); - } - - /** - * The method creates a {@link NavigationHelper} index for the given EMF model root. - * A new instance will be created on every call. - *

- * A NavigationHelper in wildcard mode will process and index all EStructuralFeatures, EClasses and EDatatypes. If - * wildcard mode is off, the client will have to manually register the interesting aspects of the model. - *

- * If the dynamic model flag is set to true, the index will use String ids to distinguish between the various - * {@link EStructuralFeature}, {@link EClass} and {@link EDataType} instances. This way the index is able to - * handle dynamic EMF instance models too. - * - * @see NavigationHelper - * - * @param emfRoot - * the root of the EMF tree to be indexed. Recommended: Resource or ResourceSet. Can be null - you can - * add a root later using {@link NavigationHelper#addRoot(Notifier)} - * @param wildcardMode - * true if all aspects of the EMF model should be indexed automatically, false if manual registration of - * interesting aspects is desirable - * @param dynamicModel - * true if the index should use String ids (nsURIs) for the various EMF types and features, and treat - * multiple EPackages sharing an nsURI as the same. false if dynamic model support is not required - * @param logger - * the log output where errors will be logged if encountered during the operation of the - * NavigationHelper; if null, the default logger for {@link NavigationHelper} is used. - * @return the NavigationHelper instance - * @throws ViatraQueryRuntimeException - */ - public NavigationHelper createNavigationHelper(Notifier emfRoot, boolean wildcardMode, boolean dynamicModel, Logger logger) { - BaseIndexOptions options = new BaseIndexOptions(dynamicModel, wildcardMode ? IndexingLevel.FULL : IndexingLevel.NONE); - return createNavigationHelper(emfRoot, options, logger); - } - - /** - * The method creates a {@link NavigationHelper} index for the given EMF model root. - * A new instance will be created on every call. - *

- * For details of base index options including wildcard and dynamic EMF mode, see {@link BaseIndexOptions}. - * - * @see NavigationHelper - * - * @param emfRoot - * the root of the EMF tree to be indexed. Recommended: Resource or ResourceSet. Can be null - you can - * add a root later using {@link NavigationHelper#addRoot(Notifier)} - * @param options the options used by the index - * @param logger - * the log output where errors will be logged if encountered during the operation of the - * NavigationHelper; if null, the default logger for {@link NavigationHelper} is used. - * @return the NavigationHelper instance - * @throws ViatraQueryRuntimeException - */ - public NavigationHelper createNavigationHelper(Notifier emfRoot, BaseIndexOptions options, Logger logger) { - Logger l = logger; - if (l == null) - l = Logger.getLogger(NavigationHelper.class); - return new NavigationHelperImpl(emfRoot, options, l); - } - - - - /** - * The method creates a TransitiveClosureHelper instance for the given EMF model root. - * A new instance will be created on every call. - * - *

- * One must specify the set of EReferences that will be considered as edges. The set can contain multiple elements; - * this way one can query forward and backward reachability information along heterogenous paths. - * - * @param emfRoot - * the root of the EMF tree to be processed. Recommended: Resource or ResourceSet. - * @param referencesToObserve - * the set of references to observe - * @return the TransitiveClosureHelper instance - * @throws ViatraQueryRuntimeException if the creation of the internal NavigationHelper failed - */ - public TransitiveClosureHelper createTransitiveClosureHelper(Notifier emfRoot, Set referencesToObserve) { - return new TransitiveClosureHelperImpl(getInstance().createNavigationHelper(emfRoot, false, null), true, referencesToObserve); - } - - /** - * The method creates a TransitiveClosureHelper instance built on an existing NavigationHelper. - * A new instance will be created on every call. - * - *

- * One must specify the set of EReferences that will be considered as edges. The set can contain multiple elements; - * this way one can query forward and backward reachability information along heterogenous paths. - * - * @param baseIndex - * the already existing NavigationHelper index on the model - * @param referencesToObserve - * the set of references to observe - * @return the TransitiveClosureHelper instance - */ - public TransitiveClosureHelper createTransitiveClosureHelper(NavigationHelper baseIndex, Set referencesToObserve) { - return new TransitiveClosureHelperImpl(baseIndex, false, referencesToObserve); - } - - -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/filters/IBaseIndexFeatureFilter.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/filters/IBaseIndexFeatureFilter.java deleted file mode 100644 index 8929b2ab..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/filters/IBaseIndexFeatureFilter.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (c) 2010-2016, Peter Lunk, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - */ -package tools.refinery.viatra.runtime.base.api.filters; - -import org.eclipse.emf.ecore.EStructuralFeature; - -/** - * - * Defines if an {@link EStructuralFeature} should not be indexed by VIATRA Base. This filtering - * method should only be used if the input metamodel has certain features, that the base indexer - * cannot handle. If the filtered feature is a containment feature, the whole sub-tree accessible - * through the said feature will be filtered. - * - * Note: This API feature is for advanced users only. Usage of this feature is not encouraged, - * unless the filtering task is impossible via using the more straightforward - * {@link IBaseIndexResourceFilter} or {@link IBaseIndexObjectFilter}. - * - * @author Peter Lunk - * @since 1.5 - * - */ -public interface IBaseIndexFeatureFilter { - - /** - * Decides whether the selected {@link EStructuralFeature} is filtered. - * - * @param feature - * @return true, if the feature should not be indexed - */ - boolean isFiltered(EStructuralFeature feature); - -} \ No newline at end of file diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/filters/IBaseIndexObjectFilter.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/filters/IBaseIndexObjectFilter.java deleted file mode 100644 index e1e46bbd..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/filters/IBaseIndexObjectFilter.java +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2014, Zoltan Ujhelyi, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api.filters; - -import org.eclipse.emf.common.notify.Notifier; - -/** - * - * Stores a collection of {@link Notifier} instances that need not to be indexed by VIATRA Base. - * - * @author Zoltan Ujhelyi - * - */ -public interface IBaseIndexObjectFilter { - - /** - * Decides whether the selected notifier is filtered. - * - * @param notifier - * @return true, if the notifier should not be indexed - */ - boolean isFiltered(Notifier notifier); - -} \ No newline at end of file diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/filters/IBaseIndexResourceFilter.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/filters/IBaseIndexResourceFilter.java deleted file mode 100644 index 73d3e961..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/filters/IBaseIndexResourceFilter.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2014, Zoltan Ujhelyi, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api.filters; - -import org.eclipse.emf.ecore.resource.Resource; - -/** - * Defines a filter for indexing resources - * @author Zoltan Ujhelyi - * - */ -public interface IBaseIndexResourceFilter { - - /** - * Decides whether a selected resource needs to be indexed - * @param resource - * @return true, if the selected resource is filtered - */ - boolean isResourceFiltered(Resource resource); - -} \ No newline at end of file diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/filters/SimpleBaseIndexFilter.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/filters/SimpleBaseIndexFilter.java deleted file mode 100644 index 9ae88a1a..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/filters/SimpleBaseIndexFilter.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2014, Zoltan Ujhelyi, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api.filters; - -import org.eclipse.emf.common.notify.Notifier; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -/** - * An index filter that is based on a collection of {@link Notifier} instances. - * - * @author Zoltan Ujhelyi - * - */ -public class SimpleBaseIndexFilter implements IBaseIndexObjectFilter { - - Set filters; - - /** - * Creates a filter using a collection of (Resource and) Notifier instances. Every containment subtree, selected by - * the given Notifiers are filtered out. - * - * @param filterConfiguration - */ - public SimpleBaseIndexFilter(Collection filterConfiguration) { - filters = new HashSet<>(filterConfiguration); - } - - public SimpleBaseIndexFilter(SimpleBaseIndexFilter other) { - this(other.filters); - } - - @Override - public boolean isFiltered(Notifier notifier) { - return filters.contains(notifier); - } - -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/profiler/BaseIndexProfiler.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/profiler/BaseIndexProfiler.java deleted file mode 100644 index d3cc152e..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/profiler/BaseIndexProfiler.java +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2019, Zoltan Ujhelyi, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api.profiler; - -import tools.refinery.viatra.runtime.base.api.NavigationHelper; -import tools.refinery.viatra.runtime.base.core.NavigationHelperContentAdapter; -import tools.refinery.viatra.runtime.base.core.NavigationHelperImpl; -import tools.refinery.viatra.runtime.base.core.profiler.ProfilingNavigationHelperContentAdapter; -import tools.refinery.viatra.runtime.matchers.util.Preconditions; - -/** - * An index profiler can be attached to an existing navigation helper instance to access the profiling data and control - * the profiler itself. If the NavigationHelper was not started in profiling mode, the profiler cannot be initialized. - * - * @since 2.3 - */ -public class BaseIndexProfiler { - - ProfilingNavigationHelperContentAdapter adapter; - - /** - * - * @throws IllegalArgumentException if the profiler cannot be attached to the base index instance - */ - public BaseIndexProfiler(NavigationHelper navigationHelper) { - if (navigationHelper instanceof NavigationHelperImpl) { - final NavigationHelperContentAdapter contentAdapter = ((NavigationHelperImpl) navigationHelper).getContentAdapter(); - if (contentAdapter instanceof ProfilingNavigationHelperContentAdapter) { - adapter = (ProfilingNavigationHelperContentAdapter)contentAdapter; - } - } - Preconditions.checkArgument(adapter != null, "Cannot attach profiler to Base Index"); - } - - /** - * Returns the number of external request (e.g. model changes) the profiler recorded. - */ - public long getNotificationCount() { - return adapter.getNotificationCount(); - } - - /** - * Return the total time base index profiler recorded for reacting to model operations. - */ - public long getTotalMeasuredTimeInMS() { - return adapter.getTotalMeasuredTimeInMS(); - } - - /** - * Returns whether the profiler is turned on (e.g. measured values are increased). - */ - public boolean isEnabled() { - return adapter.isEnabled(); - } - - /** - * Enables the base index profiling (e.g. measured values are increased) - */ - public void setEnabled(boolean isEnabled) { - adapter.setEnabled(isEnabled); - } - - /** - * Resets all measurements to 0, regardless whether the profiler is enabled or not. - *

- * - * Note: The behavior of the profiler is undefined when the measurements are reset while an EMF - * notification is being processed and the profiler is enabled. - */ - public void resetMeasurement() { - adapter.resetMeasurement(); - } -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/profiler/ProfilerMode.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/profiler/ProfilerMode.java deleted file mode 100644 index 74901263..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/api/profiler/ProfilerMode.java +++ /dev/null @@ -1,22 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2019, Zoltan Ujhelyi, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.api.profiler; - -/** - * @since 2.3 - */ -public enum ProfilerMode { - - /** The base index profiler is not available */ - OFF, - /** The profiler is initialized but not started until necessary */ - START_DISABLED, - /** The profiler is initialized and started by default */ - START_ENABLED -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/comprehension/EMFModelComprehension.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/comprehension/EMFModelComprehension.java deleted file mode 100644 index bde93367..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/comprehension/EMFModelComprehension.java +++ /dev/null @@ -1,356 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004-2010 Gabor Bergmann and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.base.comprehension; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.emf.common.notify.Notifier; -import org.eclipse.emf.common.util.EList; -import org.eclipse.emf.ecore.EAttribute; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.EcorePackage; -import org.eclipse.emf.ecore.InternalEObject; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.emf.ecore.util.EcoreUtil; -import org.eclipse.emf.ecore.util.ExtendedMetaData; -import org.eclipse.emf.ecore.util.FeatureMap; -import org.eclipse.emf.ecore.util.FeatureMap.Entry; -import org.eclipse.emf.ecore.util.InternalEList; -import tools.refinery.viatra.runtime.base.api.BaseIndexOptions; -import tools.refinery.viatra.runtime.base.api.filters.IBaseIndexFeatureFilter; -import tools.refinery.viatra.runtime.base.api.filters.IBaseIndexObjectFilter; -import tools.refinery.viatra.runtime.base.api.filters.IBaseIndexResourceFilter; - -/** - * @author Bergmann Gábor - * - * Does not directly visit derived links, unless marked as a WellBehavingFeature. Derived edges are - * automatically interpreted correctly in these cases: - EFeatureMaps - eOpposites of containments - * - * @noextend This class is not intended to be subclassed by clients. - */ -public class EMFModelComprehension { - - /** - * @since 2.3 - */ - protected BaseIndexOptions options; - - /** - * Creates a model comprehension with the specified options. The options are copied, therefore subsequent changes - * will not affect the comprehension. - */ - public EMFModelComprehension(BaseIndexOptions options) { - this.options = options.copy(); - } - - /** - * Should not traverse this feature directly. It is still possible that it can be represented in IQBase if - * {@link #representable(EStructuralFeature)} is true. - */ - public boolean untraversableDirectly(EStructuralFeature feature) { - - if((feature instanceof EReference && ((EReference)feature).isContainer())) { - // container features are always represented through their opposite - return true; - } - - //If the feature is filtered by the feature filter specified in the BaseIndexOptions, return true - final IBaseIndexFeatureFilter featureFilter = options.getFeatureFilterConfiguration(); - if(featureFilter != null && featureFilter.isFiltered(feature)){ - return true; - } - - boolean suspect = onlySamplingFeature(feature); - if(suspect) { - // even if the feature can only be sampled, it may be used if the proper base index option is set - suspect = options.isTraverseOnlyWellBehavingDerivedFeatures(); - } - return suspect; - } - - /** - * Decides whether a feature can only be sampled as there is no guarantee that proper notifications will be - * delivered by their implementation. - * - *

Such features are derived (and/or volatile) features that are not well-behaving. - */ - public boolean onlySamplingFeature(EStructuralFeature feature) { - boolean suspect = - feature.isDerived() || - feature.isVolatile(); - if (suspect) { - // override support here - // (e.g. if manual notifications available, or no changes expected afterwards) - suspect = !WellbehavingDerivedFeatureRegistry.isWellbehavingFeature(feature); - // TODO verbose flag somewhere to ease debugging (for such warnings) - // TODO add warning about not visited subtree (containment, FeatureMap and annotation didn't define - // otherwise) - } - return suspect; - } - - /** - * This feature can be represented in IQBase. - */ - public boolean representable(EStructuralFeature feature) { - if (!untraversableDirectly(feature)) - return true; - - if (feature instanceof EReference) { - final EReference reference = (EReference) feature; - if (reference.isContainer() && representable(reference.getEOpposite())) - return true; - } - - boolean isMixed = "mixed".equals(EcoreUtil.getAnnotation(feature.getEContainingClass(), - ExtendedMetaData.ANNOTATION_URI, "kind")); - if (isMixed) - return true; // TODO maybe check the "name"=":mixed" or ":group" feature for representability? - - // Group features are alternative features that are used when the ecore is derived from an xsd schema containing - // choices; in that case instead of the asked feature we should index the corresponding group feature - final EStructuralFeature groupFeature = ExtendedMetaData.INSTANCE.getGroup(feature); - if (groupFeature != null) { - return representable(groupFeature); - } - - return false; - } - - /** - * Resource filters not consulted here (for performance), because model roots are assumed to be pre-filtered. - */ - public void traverseModel(EMFVisitor visitor, Notifier source) { - if (source == null) - return; - if (source instanceof EObject) { - final EObject sourceObject = (EObject) source; - if (sourceObject.eIsProxy()) - throw new IllegalArgumentException("Proxy EObject cannot act as model roots for VIATRA: " + source); - traverseObject(visitor, sourceObject); - } else if (source instanceof Resource) { - traverseResource(visitor, (Resource) source); - } else if (source instanceof ResourceSet) { - traverseResourceSet(visitor, (ResourceSet) source); - } - } - - public void traverseResourceSet(EMFVisitor visitor, ResourceSet source) { - if (source == null) - return; - final List resources = new ArrayList(source.getResources()); - for (Resource resource : resources) { - traverseResourceIfUnfiltered(visitor, resource); - } - } - - public void traverseResourceIfUnfiltered(EMFVisitor visitor, Resource resource) { - final IBaseIndexResourceFilter resourceFilter = options.getResourceFilterConfiguration(); - if (resourceFilter != null && resourceFilter.isResourceFiltered(resource)) - return; - final IBaseIndexObjectFilter objectFilter = options.getObjectFilterConfiguration(); - if (objectFilter != null && objectFilter.isFiltered(resource)) - return; - - traverseResource(visitor, resource); - } - - public void traverseResource(EMFVisitor visitor, Resource source) { - if (source == null) - return; - if (visitor.pruneSubtrees(source)) - return; - final EList contents = source.getContents(); - for (EObject eObject : contents) { - traverseObjectIfUnfiltered(visitor, eObject); - } - } - - - public void traverseObjectIfUnfiltered(EMFVisitor visitor, EObject targetObject) { - final IBaseIndexObjectFilter objectFilter = options.getObjectFilterConfiguration(); - if (objectFilter != null && objectFilter.isFiltered(targetObject)) - return; - - traverseObject(visitor, targetObject); - } - - public void traverseObject(EMFVisitor visitor, EObject source) { - if (source == null) - return; - - if (visitor.preOrder()) visitor.visitElement(source); - for (EStructuralFeature feature : source.eClass().getEAllStructuralFeatures()) { - if (untraversableDirectly(feature)) - continue; - final boolean visitorPrunes = visitor.pruneFeature(feature); - if (visitorPrunes && !unprunableFeature(visitor, source, feature)) - continue; - - traverseFeatureTargets(visitor, source, feature, visitorPrunes); - } - if (!visitor.preOrder()) visitor.visitElement(source); - } - - protected void traverseFeatureTargets(EMFVisitor visitor, EObject source, EStructuralFeature feature, - final boolean visitorPrunes) { - boolean attemptResolve = (feature instanceof EAttribute) || visitor.attemptProxyResolutions(source, (EReference)feature); - if (feature.isMany()) { - EList targets = (EList) source.eGet(feature); - int position = 0; - Iterator iterator = attemptResolve ? targets.iterator() : ((InternalEList)targets).basicIterator(); - while (iterator.hasNext()) { - Object target = iterator.next(); - traverseFeatureInternal(visitor, source, feature, target, visitorPrunes, position++); - } - } else { - Object target = source.eGet(feature, attemptResolve); - if (target != null) - traverseFeatureInternal(visitor, source, feature, target, visitorPrunes, null); - } - } - /** - * @since 2.3 - */ - protected boolean unprunableFeature(EMFVisitor visitor, EObject source, EStructuralFeature feature) { - return (feature instanceof EAttribute && EcorePackage.eINSTANCE.getEFeatureMapEntry().equals( - ((EAttribute) feature).getEAttributeType())) - || (feature instanceof EReference && ((EReference) feature).isContainment() && (!visitor - .pruneSubtrees(source) || ((EReference) feature).getEOpposite() != null)); - } - - /** - * @param position optional: known position in multivalued collection (for more efficient proxy resolution) - */ - public void traverseFeature(EMFVisitor visitor, EObject source, EStructuralFeature feature, Object target, Integer position) { - if (target == null) - return; - if (untraversableDirectly(feature)) - return; - traverseFeatureInternalSimple(visitor, source, feature, target, position); - } - - /** - * @param position optional: known position in multivalued collection (for more efficient proxy resolution) - * @since 2.3 - */ - protected void traverseFeatureInternalSimple(EMFVisitor visitor, EObject source, EStructuralFeature feature, - Object target, Integer position) { - final boolean visitorPrunes = visitor.pruneFeature(feature); - if (visitorPrunes && !unprunableFeature(visitor, source, feature)) - return; - - traverseFeatureInternal(visitor, source, feature, target, visitorPrunes, position); - } - - /** - * @pre target != null - * @param position optional: known position in multivalued collection (for more efficient proxy resolution) - * @since 2.3 - */ - protected void traverseFeatureInternal(EMFVisitor visitor, EObject source, EStructuralFeature feature, - Object target, boolean visitorPrunes, Integer position) { - if (feature instanceof EAttribute) { - if (!visitorPrunes) - visitor.visitAttribute(source, (EAttribute) feature, target); - if (target instanceof FeatureMap.Entry) { // emulated derived edge based on FeatureMap - Entry entry = (FeatureMap.Entry) target; - final EStructuralFeature emulated = entry.getEStructuralFeature(); - final Object emulatedTarget = entry.getValue(); - - emulateUntraversableFeature(visitor, source, emulated, emulatedTarget); - } - } else if (feature instanceof EReference) { - EReference reference = (EReference) feature; - EObject targetObject = (EObject) target; - if (reference.isContainment()) { - if (!visitor.avoidTransientContainmentLink(source, reference, targetObject)) { - if (!visitorPrunes) - visitor.visitInternalContainment(source, reference, targetObject); - if (!visitor.pruneSubtrees(source)) { - // Recursively follow containment... - // unless cross-resource containment (in which case we may skip) - Resource targetResource = (targetObject instanceof InternalEObject)? - ((InternalEObject)targetObject).eDirectResource() : null; - boolean crossResourceContainment = targetResource != null; - if (!crossResourceContainment || visitor.descendAlongCrossResourceContainments()) { - // in-resource containment shall be followed - // as well as cross-resource containment for an object scope - traverseObjectIfUnfiltered(visitor, targetObject); - } else { - // do not follow - // target will be traversed separately from its resource (resourceSet scope) - // or left out of scope (resource scope) - } - } - - final EReference opposite = reference.getEOpposite(); - if (opposite != null) { // emulated derived edge based on container opposite - emulateUntraversableFeature(visitor, targetObject, opposite, source); - } - } - } else { - // if (containedElements.contains(target)) - if (!visitorPrunes) - visitor.visitNonContainmentReference(source, reference, targetObject); - } - if (targetObject.eIsProxy()) { - if (!reference.isResolveProxies()) { - throw new IllegalStateException(String.format( - "EReference '%s' of EClass %s is set as proxy-non-resolving (i.e. it should never point to a proxy, and never lead cross-resource), " + - "yet VIATRA Base encountered a proxy object %s referenced from %s.", - reference.getName(), reference.getEContainingClass().getInstanceTypeName(), - targetObject, source)); - } - visitor.visitProxyReference(source, reference, targetObject, position); - } - } - - } - - - /** - * Emulates a derived edge, if it is not visited otherwise - * - * @pre target != null - * @since 2.3 - */ - protected void emulateUntraversableFeature(EMFVisitor visitor, EObject source, - final EStructuralFeature emulated, final Object target) { - if (untraversableDirectly(emulated)) - traverseFeatureInternalSimple(visitor, source, emulated, target, null); - } - - /** - * Can be called to attempt to resolve a reference pointing to one or more proxies, using eGet(). - */ - @SuppressWarnings("unchecked") - public void tryResolveReference(EObject source, EReference reference) { - final Object result = source.eGet(reference, true); - if (reference.isMany()) { - // no idea which element to get, have to iterate through - ((Iterable) result).forEach(EObject -> {/*proxy resolution as a side-effect of traversal*/}); - } - } - - /** - * Finds out whether the Resource is currently loading - */ - public boolean isLoading(Resource resource) { - return !resource.isLoaded() || ((Resource.Internal)resource).isLoading(); - } - -} \ No newline at end of file diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/comprehension/EMFVisitor.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/comprehension/EMFVisitor.java deleted file mode 100644 index 6029bb02..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/comprehension/EMFVisitor.java +++ /dev/null @@ -1,145 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004-2010 Gabor Bergmann and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.base.comprehension; - -import org.eclipse.emf.ecore.EAttribute; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.resource.Resource; - -/** - * Use EMFModelComprehension to visit an EMF model. - * - * @author Bergmann Gábor - * - */ -// FIXME: -// - handle boundary of active emfRoot subtree -// - more efficient traversal -public class EMFVisitor { - - boolean preOrder; - - public EMFVisitor(boolean preOrder) { - super(); - this.preOrder = preOrder; - } - - /** - * @param resource - * @param element - */ - public void visitTopElementInResource(Resource resource, EObject element) { - } - - /** - * @param resource - */ - public void visitResource(Resource resource) { - } - - /** - * @param source - */ - public void visitElement(EObject source) { - } - - /** - * @param source - * @param feature - * @param target - */ - public void visitNonContainmentReference(EObject source, EReference feature, EObject target) { - } - - /** - * @param source - * @param feature - * @param target - */ - public void visitInternalContainment(EObject source, EReference feature, EObject target) { - } - - /** - * @param source - * @param feature - * @param target - */ - public void visitAttribute(EObject source, EAttribute feature, Object target) { - } - - /** - * Returns true if the given feature should not be traversed (interesting esp. if multi-valued) - */ - public boolean pruneFeature(EStructuralFeature feature) { - return false; - } - - /** - * Returns true if the contents of an object should be pruned (and not explored by the visitor) - */ - public boolean pruneSubtrees(EObject source) { - return false; - } - - /** - * Returns true if the contents of a resource should be pruned (and not explored by the visitor) - */ - public boolean pruneSubtrees(Resource source) { - return false; - } - - /** - * An opportunity for the visitor to indicate that the containment link is considered in a transient state, and the - * model comprehension should avoid following it. - * - * A containment is in a transient state from the point of view of the visitor if it connects a subtree that is - * being inserted during a full-model traversal, and a separate notification handler will deal with it - * later. - */ - public boolean avoidTransientContainmentLink(EObject source, EReference reference, EObject targetObject) { - return false; - } - - /** - * @return if objects should be visited before their outgoing edges - */ - public boolean preOrder() { - return preOrder; - } - - /** - * Called after visiting the reference, if the target is a proxy. - * - * @param position - * optional: known position in multivalued collection (for more efficient proxy resolution) - */ - public void visitProxyReference(EObject source, EReference reference, EObject targetObject, Integer position) { - } - - /** - * Whether the given reference of the given object should be resolved when it is a proxy - */ - public boolean attemptProxyResolutions(EObject source, EReference feature) { - return true; - } - - /** - * @return true if traversing visitors shall descend along cross-resource containments - * (this only makes sense for traversing visitors on an object scope) - * - * @since 1.7 - */ - public boolean descendAlongCrossResourceContainments() { - return false; - } - -} \ No newline at end of file diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/comprehension/WellbehavingDerivedFeatureRegistry.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/comprehension/WellbehavingDerivedFeatureRegistry.java deleted file mode 100644 index d696ddd6..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/comprehension/WellbehavingDerivedFeatureRegistry.java +++ /dev/null @@ -1,154 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004-2011 Abel Hegedus and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.comprehension; - -import java.util.Collection; -import java.util.Collections; -import java.util.WeakHashMap; - -import org.apache.log4j.Logger; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.IExtensionRegistry; -import org.eclipse.core.runtime.Platform; -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EClassifier; -import org.eclipse.emf.ecore.EPackage; -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.base.ViatraBasePlugin; - -/** - * @author Abel Hegedus - * - */ -public class WellbehavingDerivedFeatureRegistry { - - - private static Collection contributedWellbehavingDerivedFeatures = Collections.newSetFromMap(new WeakHashMap()); - private static Collection contributedWellbehavingDerivedClasses = Collections.newSetFromMap(new WeakHashMap()); - private static Collection contributedWellbehavingDerivedPackages = Collections.newSetFromMap(new WeakHashMap()); - - private WellbehavingDerivedFeatureRegistry() { - } - - /** - * Called by ViatraBasePlugin. - */ - public static void initRegistry() { - getContributedWellbehavingDerivedFeatures().clear(); - getContributedWellbehavingDerivedClasses().clear(); - getContributedWellbehavingDerivedPackages().clear(); - - IExtensionRegistry reg = Platform.getExtensionRegistry(); - IExtensionPoint poi; - - poi = reg.getExtensionPoint(ViatraBasePlugin.WELLBEHAVING_DERIVED_FEATURE_EXTENSION_POINT_ID); - if (poi != null) { - IExtension[] exts = poi.getExtensions(); - - for (IExtension ext : exts) { - - IConfigurationElement[] els = ext.getConfigurationElements(); - for (IConfigurationElement el : els) { - if (el.getName().equals("wellbehaving-derived-feature")) { - processWellbehavingExtension(el); - } else { - throw new UnsupportedOperationException("Unknown configuration element " + el.getName() - + " in plugin.xml of " + el.getDeclaringExtension().getUniqueIdentifier()); - } - } - } - } - } - - private static void processWellbehavingExtension(IConfigurationElement el) { - try { - String packageUri = el.getAttribute("package-nsUri"); - String featureName = el.getAttribute("feature-name"); - String classifierName = el.getAttribute("classifier-name"); - String contributorName = el.getContributor().getName(); - StringBuilder featureIdBuilder = new StringBuilder(); - if (packageUri != null) { - EPackage pckg = EPackage.Registry.INSTANCE.getEPackage(packageUri); - featureIdBuilder.append(packageUri); - if (pckg != null) { - if (classifierName != null) { - EClassifier clsr = pckg.getEClassifier(classifierName); - featureIdBuilder.append("##").append(classifierName); - if (clsr instanceof EClass) { - if (featureName != null) { - EClass cls = (EClass) clsr; - EStructuralFeature feature = cls.getEStructuralFeature(featureName); - featureIdBuilder.append("##").append(featureName); - if (feature != null) { - registerWellbehavingDerivedFeature(feature); - } else { - throw new IllegalStateException(String.format("Feature %s of EClass %s in package %s not found! (plug-in %s)", featureName, classifierName, packageUri, contributorName)); - } - } else { - registerWellbehavingDerivedClass((EClass) clsr); - } - } else { - throw new IllegalStateException(String.format("EClassifier %s does not exist in package %s! (plug-in %s)", classifierName, packageUri, contributorName)); - } - } else { - if(featureName != null){ - throw new IllegalStateException(String.format("Feature name must be empty if classifier name is not set! (package %s, plug-in %s)", packageUri, contributorName)); - } - registerWellbehavingDerivedPackage(pckg); - } - } - } - } catch (Exception e) { - final Logger logger = Logger.getLogger(WellbehavingDerivedFeatureRegistry.class); - logger.error("Well-behaving feature registration failed", e); - } - } - - /** - * - * @param feature - * @return true if the feature (or its defining EClass or ) is registered as well-behaving - */ - public static boolean isWellbehavingFeature(EStructuralFeature feature) { - if(feature == null){ - return false; - } else if (contributedWellbehavingDerivedFeatures.contains(feature)) { - return true; - } else if (contributedWellbehavingDerivedClasses.contains(feature.getEContainingClass())) { - return true; - } else return contributedWellbehavingDerivedPackages.contains(feature.getEContainingClass().getEPackage()); - } - - public static void registerWellbehavingDerivedFeature(EStructuralFeature feature) { - contributedWellbehavingDerivedFeatures.add(feature); - } - - public static void registerWellbehavingDerivedClass(EClass cls) { - contributedWellbehavingDerivedClasses.add(cls); - } - - public static void registerWellbehavingDerivedPackage(EPackage pkg) { - contributedWellbehavingDerivedPackages.add(pkg); - } - - public static Collection getContributedWellbehavingDerivedFeatures() { - return contributedWellbehavingDerivedFeatures; - } - - public static Collection getContributedWellbehavingDerivedClasses() { - return contributedWellbehavingDerivedClasses; - } - - public static Collection getContributedWellbehavingDerivedPackages() { - return contributedWellbehavingDerivedPackages; - } - -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/AbstractBaseIndexStore.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/AbstractBaseIndexStore.java deleted file mode 100644 index 3d61b1bf..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/AbstractBaseIndexStore.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2017, Zoltan Ujhelyi, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.core; - -import org.apache.log4j.Logger; -import tools.refinery.viatra.runtime.base.api.BaseIndexOptions; - -/** - * @since 1.6 - */ -public class AbstractBaseIndexStore { - - protected final NavigationHelperImpl navigationHelper; - protected final Logger logger; - protected final BaseIndexOptions options; - - public AbstractBaseIndexStore(NavigationHelperImpl navigationHelper, Logger logger) { - this.navigationHelper = navigationHelper; - this.logger = logger; - this.options = navigationHelper.getBaseIndexOptions(); - } -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/EMFBaseIndexInstanceStore.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/EMFBaseIndexInstanceStore.java deleted file mode 100644 index 2094bbbe..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/EMFBaseIndexInstanceStore.java +++ /dev/null @@ -1,451 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.core; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.apache.log4j.Logger; -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EClassifier; -import org.eclipse.emf.ecore.EObject; -import tools.refinery.viatra.runtime.base.api.IStructuralFeatureInstanceProcessor; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory; -import tools.refinery.viatra.runtime.matchers.util.IMultiset; - -/** - * Stores the indexed contents of an EMF model - * (includes instance model information). - * - * @author Gabor Bergmann - * @noextend This class is not intended to be subclassed by clients. - */ -public class EMFBaseIndexInstanceStore extends AbstractBaseIndexStore { - - public EMFBaseIndexInstanceStore(NavigationHelperImpl navigationHelper, Logger logger) { - super(navigationHelper, logger); - } - - /** - * since last run of after-update callbacks - */ - boolean isDirty = false; - - /** - * feature (EAttribute or EReference or equivalent String key) -> FeatureData - * @since 1.7 - */ - private Map featureDataMap = CollectionsFactory.createMap(); - - /** - * value -> featureKey(s); - * constructed on-demand, null if unused (hopefully most of the time) - */ - private Map> valueToFeatureMap = null; - - - /** - * key (String id or EClass instance) -> instance(s) - */ - private final Map> instanceMap = CollectionsFactory.createMap(); - - /** - * key (String id or EDataType instance) -> multiset of value(s) - */ - private final Map> dataTypeMap = CollectionsFactory.createMap(); - - /** - * Bundles all instance store data specific to a given binary feature. - * - *

TODO: specialize for to-one features and unique to-many features - *

TODO: on-demand construction of valueToHolderMap - * - * @author Gabor Bergmann - * @since 1.7 - */ - class FeatureData { - /** value -> holder(s) */ - private Map> valueToHolderMap = CollectionsFactory.createMap(); - /** - * holder -> value(s); - * constructed on-demand, null if unused - */ - private Map> holderToValueMap; - - /** - * feature (EAttribute or EReference) or its string key (in dynamic EMF mode) - */ - private Object featureKey; - - /** - * @return feature (EAttribute or EReference) or its string key (in dynamic EMF mode) - */ - public Object getFeatureKey() { - return featureKey; - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + ":" + featureKey; - } - - /** - * @return true if this was the first time the value was added to this feature of this holder (false is only - * expected for non-unique features) - */ - boolean insertFeatureTuple(boolean unique, final Object value, final EObject holder) { - // TODO we currently assume V2H map exists - boolean changed = addToValueToHolderMap(value, holder); - if (holderToValueMap != null) { - addToHolderToValueMap(value, holder); - } - - if (unique && !changed) { - navigationHelper.logIncidentFeatureTupleInsertion(value, holder, featureKey); - } - return changed; - } - - /** - * @return true if this was the last duplicate of the value added to this feature of this holder (false is only - * expected for non-unique features) - */ - boolean removeFeatureTuple(boolean unique, final Object value, final EObject holder) { - Object featureKey = getFeatureKey(); - try { - // TODO we currently assume V2H map exists - boolean changed = removeFromValueToHolderMap(value, holder); - if (holderToValueMap != null) { - removeFromHolderToValueMap(value, holder); - } - - if (unique && !changed) { - navigationHelper.logIncidentFeatureTupleRemoval(value, holder, featureKey); - } - return changed; - } catch (IllegalStateException ex) { - navigationHelper.logIncidentFeatureTupleRemoval(value, holder, featureKey); - return false; - } - } - - - protected boolean addToHolderToValueMap(Object value, EObject holder) { - IMultiset values = holderToValueMap.computeIfAbsent(holder, - CollectionsFactory::emptyMultiset); - boolean changed = values.addOne(value); - return changed; - } - - protected boolean addToValueToHolderMap(final Object value, final EObject holder) { - IMultiset holders = valueToHolderMap.computeIfAbsent(value, - CollectionsFactory::emptyMultiset); - boolean changed = holders.addOne(holder); - return changed; - } - - protected boolean removeFromHolderToValueMap(Object value, EObject holder) throws IllegalStateException { - IMultiset values = holderToValueMap.get(holder); - if (values == null) - throw new IllegalStateException(); - boolean changed = values.removeOne(value); - if (changed && values.isEmpty()) - holderToValueMap.remove(holder); - return changed; - } - protected boolean removeFromValueToHolderMap(final Object value, final EObject holder) throws IllegalStateException { - IMultiset holders = valueToHolderMap.get(value); - if (holders == null) - throw new IllegalStateException(); - boolean changed = holders.removeOne(holder); - if (changed && holders.isEmpty()) - valueToHolderMap.remove(value); - return changed; - } - - protected Map> getHolderToValueMap() { - if (holderToValueMap == null) { - holderToValueMap = CollectionsFactory.createMap(); - - // TODO we currently assume V2H map exists - for (Entry> entry : valueToHolderMap.entrySet()) { - Object value = entry.getKey(); - IMultiset holders = entry.getValue(); - for (EObject holder : holders.distinctValues()) { - int count = holders.getCount(holder); - - IMultiset valuesOfHolder = holderToValueMap.computeIfAbsent(holder, - CollectionsFactory::emptyMultiset); - valuesOfHolder.addPositive(value, count); - } - } - } - return holderToValueMap; - } - protected Map> getValueToHolderMap() { - // TODO we currently assume V2H map exists - return valueToHolderMap; - } - - public void forEach(IStructuralFeatureInstanceProcessor processor) { - // TODO we currently assume V2H map exists - if (valueToHolderMap != null) { - for (Entry> entry : valueToHolderMap.entrySet()) { - Object value = entry.getKey(); - for (EObject eObject : entry.getValue().distinctValues()) { - processor.process(eObject, value); - } - } - } else throw new UnsupportedOperationException("TODO implement"); - } - - public Set getAllDistinctHolders() { - return getHolderToValueMap().keySet(); - } - - public Set getAllDistinctValues() { - return getValueToHolderMap().keySet(); - } - - public Set getDistinctHoldersOfValue(Object value) { - IMultiset holdersMultiset = getValueToHolderMap().get(value); - if (holdersMultiset == null) - return Collections.emptySet(); - else return holdersMultiset.distinctValues(); - } - - - public Set getDistinctValuesOfHolder(EObject holder) { - IMultiset valuesMultiset = getHolderToValueMap().get(holder); - if (valuesMultiset == null) - return Collections.emptySet(); - else return valuesMultiset.distinctValues(); - } - - public boolean isInstance(EObject source, Object target) { - // TODO we currently assume V2H map exists - if (valueToHolderMap != null) { - IMultiset holders = valueToHolderMap.get(target); - return holders != null && holders.containsNonZero(source); - } else throw new UnsupportedOperationException("TODO implement"); - } - - - } - - - FeatureData getFeatureData(Object featureKey) { - FeatureData data = featureDataMap.get(featureKey); - if (data == null) { - data = createFeatureData(featureKey); - featureDataMap.put(featureKey, data); - } - return data; - } - - /** - * TODO: specialize for to-one features and unique to-many features - */ - protected FeatureData createFeatureData(Object featureKey) { - FeatureData data = new FeatureData(); - data.featureKey = featureKey; - return data; - } - - - - - protected void insertFeatureTuple(final Object featureKey, boolean unique, final Object value, final EObject holder) { - boolean changed = getFeatureData(featureKey).insertFeatureTuple(unique, value, holder); - if (changed) { // if not duplicated - - if (valueToFeatureMap != null) { - insertIntoValueToFeatureMap(featureKey, value); - } - - isDirty = true; - navigationHelper.notifyFeatureListeners(holder, featureKey, value, true); - } - } - - protected void removeFeatureTuple(final Object featureKey, boolean unique, final Object value, final EObject holder) { - boolean changed = getFeatureData(featureKey).removeFeatureTuple(unique, value, holder); - if (changed) { // if not duplicated - - if (valueToFeatureMap != null) { - removeFromValueToFeatureMap(featureKey, value); - } - - isDirty = true; - navigationHelper.notifyFeatureListeners(holder, featureKey, value, false); - } - } - - - public Set getFeatureKeysPointingTo(Object target) { - final IMultiset sources = getValueToFeatureMap().get(target); - return sources == null ? Collections.emptySet() : sources.distinctValues(); - } - - protected Map> getValueToFeatureMap() { - if (valueToFeatureMap == null) { // must be inverted from feature data - valueToFeatureMap = CollectionsFactory.createMap(); - for (FeatureData featureData : featureDataMap.values()) { - final Object featureKey = featureData.getFeatureKey(); - featureData.forEach((source, target) -> insertIntoValueToFeatureMap(featureKey, target)); - } - } - return valueToFeatureMap; - } - - protected void insertIntoValueToFeatureMap(final Object featureKey, Object target) { - IMultiset featureKeys = valueToFeatureMap.computeIfAbsent(target, CollectionsFactory::emptyMultiset); - featureKeys.addOne(featureKey); - } - protected void removeFromValueToFeatureMap(final Object featureKey, final Object value) { - IMultiset featureKeys = valueToFeatureMap.get(value); - if (featureKeys == null) - throw new IllegalStateException(); - featureKeys.removeOne(featureKey); - if (featureKeys.isEmpty()) - valueToFeatureMap.remove(value); - } - - // START ********* InstanceSet ********* - public Set getInstanceSet(final Object keyClass) { - return instanceMap.get(keyClass); - } - - public void removeInstanceSet(final Object keyClass) { - instanceMap.remove(keyClass); - } - - public void insertIntoInstanceSet(final Object keyClass, final EObject value) { - Set set = instanceMap.computeIfAbsent(keyClass, CollectionsFactory::emptySet); - - if (!set.add(value)) { - navigationHelper.logIncidentInstanceInsertion(keyClass, value); - } else { - isDirty = true; - navigationHelper.notifyInstanceListeners(keyClass, value, true); - } - } - - public void removeFromInstanceSet(final Object keyClass, final EObject value) { - final Set set = instanceMap.get(keyClass); - if (set != null) { - if(!set.remove(value)) { - navigationHelper.logIncidentInstanceRemoval(keyClass, value); - } else { - if (set.isEmpty()) { - instanceMap.remove(keyClass); - } - isDirty = true; - navigationHelper.notifyInstanceListeners(keyClass, value, false); - } - } else { - navigationHelper.logIncidentInstanceRemoval(keyClass, value); - } - - } - - - - // END ********* InstanceSet ********* - - // START ********* DataTypeMap ********* - public Set getDistinctDataTypeInstances(final Object keyType) { - IMultiset values = dataTypeMap.get(keyType); - return values == null ? Collections.emptySet() : values.distinctValues(); - } - - public void removeDataTypeMap(final Object keyType) { - dataTypeMap.remove(keyType); - } - - public void insertIntoDataTypeMap(final Object keyType, final Object value) { - IMultiset valMap = dataTypeMap.computeIfAbsent(keyType, CollectionsFactory::emptyMultiset); - final boolean firstOccurrence = valMap.addOne(value); - - isDirty = true; - navigationHelper.notifyDataTypeListeners(keyType, value, true, firstOccurrence); - } - - public void removeFromDataTypeMap(final Object keyType, final Object value) { - final IMultiset valMap = dataTypeMap.get(keyType); - if (valMap != null) { - final boolean lastOccurrence = valMap.removeOne(value); - if (lastOccurrence && valMap.isEmpty()) { - dataTypeMap.remove(keyType); - } - - isDirty = true; - navigationHelper.notifyDataTypeListeners(keyType, value, false, lastOccurrence); - } - } - - // END ********* DataTypeMap ********* - - protected Set getHoldersOfFeature(Object featureKey) { - FeatureData featureData = getFeatureData(featureKey); - return featureData.getAllDistinctHolders(); - } - protected Set getValuesOfFeature(Object featureKey) { - FeatureData featureData = getFeatureData(featureKey); - return featureData.getAllDistinctValues(); - } - - /** - * Returns all EClasses that currently have direct instances cached by the index. - *

- * Supertypes will not be returned, unless they have direct instances in the model as well. If not in - * wildcard mode, only registered EClasses and their subtypes will be returned. - *

- * Note for advanced users: if a type is represented by multiple EClass objects, one of them is chosen as - * representative and returned. - */ - public Set getAllCurrentClasses() { - final Set result = CollectionsFactory.createSet(); - final Set classifierKeys = instanceMap.keySet(); - for (final Object classifierKey : classifierKeys) { - final EClassifier knownClassifier = navigationHelper.metaStore.getKnownClassifierForKey(classifierKey); - if (knownClassifier instanceof EClass) { - result.add((EClass) knownClassifier); - } - } - return result; - } - - Set getOldValuesForHolderAndFeature(EObject source, Object featureKey) { - // while this is slower than using the holderToFeatureToValueMap, we do not want to construct that to avoid - // memory overhead - Map> oldValuesToHolders = getFeatureData(featureKey).valueToHolderMap; - Set oldValues = new HashSet(); - for (Entry> entry : oldValuesToHolders.entrySet()) { - if (entry.getValue().containsNonZero(source)) { - oldValues.add(entry.getKey()); - } - } - return oldValues; - } - - protected void forgetFeature(Object featureKey) { - FeatureData removed = featureDataMap.remove(featureKey); - if (valueToFeatureMap != null) { - for (Object value : removed.getAllDistinctValues()) { - removeFromValueToFeatureMap(featureKey, value); - } - } - } - - -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/EMFBaseIndexMetaStore.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/EMFBaseIndexMetaStore.java deleted file mode 100644 index 52ca3a53..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/EMFBaseIndexMetaStore.java +++ /dev/null @@ -1,380 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.core; - -import org.eclipse.emf.common.util.Enumerator; -import org.eclipse.emf.ecore.*; -import tools.refinery.viatra.runtime.base.api.BaseIndexOptions; -import tools.refinery.viatra.runtime.base.api.IndexingLevel; -import tools.refinery.viatra.runtime.base.api.InstanceListener; -import tools.refinery.viatra.runtime.base.exception.ViatraBaseException; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory.MemoryType; -import tools.refinery.viatra.runtime.matchers.util.IMemoryView; -import tools.refinery.viatra.runtime.matchers.util.IMultiLookup; -import tools.refinery.viatra.runtime.matchers.util.Preconditions; - -import java.util.*; -import java.util.Map.Entry; - -/** - * Stores the indexed metamodel information. - * - * @author Gabor Bergmann - * @noextend This class is not intended to be subclassed by clients. - */ -public class EMFBaseIndexMetaStore { - - private static final EClass EOBJECT_CLASS = EcorePackage.eINSTANCE.getEObject(); - private final boolean isDynamicModel; - private NavigationHelperImpl navigationHelper; - - /** - * - */ - public EMFBaseIndexMetaStore(final NavigationHelperImpl navigationHelper) { - this.navigationHelper = navigationHelper; - final BaseIndexOptions options = navigationHelper.getBaseIndexOptions(); - this.isDynamicModel = options.isDynamicEMFMode(); - } - - /** - * Supports collision detection and EEnum canonicalization. Used for all EPackages that have types whose instances - * were encountered at least once. - */ - private final Set knownPackages = new HashSet(); - - /** - * Field variable because it is needed for collision detection. Used for all EClasses whose instances were - * encountered at least once. - */ - private final Set knownClassifiers = new HashSet(); - /** - * Field variable because it is needed for collision detection. Used for all EStructuralFeatures whose instances - * were encountered at least once. - */ - private final Set knownFeatures = new HashSet(); - - /** - * (EClass or String ID) -> all subtypes in knownClasses - */ - private final Map> subTypeMap = new HashMap>(); - /** - * (EClass or String ID) -> all supertypes in knownClasses - */ - private final Map> superTypeMap = new HashMap>(); - - /** - * EPacakge NsURI -> EPackage instances; this is instance-level to detect collisions - */ - private final IMultiLookup uniqueIDToPackage = CollectionsFactory.createMultiLookup(Object.class, MemoryType.SETS, Object.class); - - /** - * static maps between metamodel elements and their unique IDs - */ - private final Map uniqueIDFromClassifier = new HashMap(); - private final Map uniqueIDFromTypedElement = new HashMap(); - private final Map uniqueIDFromEnumerator = new HashMap(); - private final IMultiLookup uniqueIDToClassifier = CollectionsFactory.createMultiLookup(Object.class, MemoryType.SETS, Object.class); - private final IMultiLookup uniqueIDToTypedElement = CollectionsFactory.createMultiLookup(Object.class, MemoryType.SETS, Object.class); - private final IMultiLookup uniqueIDToEnumerator = CollectionsFactory.createMultiLookup(Object.class, MemoryType.SETS, Object.class); - private final Map uniqueIDToCanonicalEnumerator = new HashMap(); - - /** - * Map from enum classes generated for {@link EEnum}s to the actual EEnum. - */ - private Map, EEnum> generatedEENumClasses = new HashMap, EEnum>(); - - /** - * @return the eObjectClassKey - */ - public Object getEObjectClassKey() { - if (eObjectClassKey == null) { - eObjectClassKey = toKey(EOBJECT_CLASS); - } - return eObjectClassKey; - } - private Object eObjectClassKey = null; - - protected Object toKey(final EClassifier classifier) { - if (isDynamicModel) { - return toKeyDynamicInternal(classifier); - } else { - maintainMetamodel(classifier); - return classifier; - } - } - - protected String toKeyDynamicInternal(final EClassifier classifier) { - String id = uniqueIDFromClassifier.get(classifier); - if (id == null) { - Preconditions.checkArgument(!classifier.eIsProxy(), - "Classifier %s is an unresolved proxy", classifier); - id = classifier.getEPackage().getNsURI() + "##" + classifier.getName(); - uniqueIDFromClassifier.put(classifier, id); - uniqueIDToClassifier.addPair(id, classifier); - // metamodel maintenance will call back toKey(), but now the ID maps are already filled - maintainMetamodel(classifier); - } - return id; - } - - protected String enumToKeyDynamicInternal(Enumerator enumerator) { - String id = uniqueIDFromEnumerator.get(enumerator); - if (id == null) { - if (enumerator instanceof EEnumLiteral) { - EEnumLiteral enumLiteral = (EEnumLiteral) enumerator; - final EEnum eEnum = enumLiteral.getEEnum(); - maintainMetamodel(eEnum); - - id = constructEnumID(eEnum.getEPackage().getNsURI(), eEnum.getName(), enumLiteral.getLiteral()); - - // there might be a generated enum for this enum literal! - // generated enum should pre-empt the ecore enum literal as canonical enumerator - Enumerator instanceEnum = enumLiteral.getInstance(); - if (instanceEnum != null && !uniqueIDToCanonicalEnumerator.containsKey(id)) { - uniqueIDToCanonicalEnumerator.put(id, instanceEnum); - } - // if generated enum not found... delay selection of canonical enumerator - } else { // generated enum - final EEnum eEnum = generatedEENumClasses.get(enumerator.getClass()); - if (eEnum != null) - id = constructEnumID(eEnum.getEPackage().getNsURI(), eEnum.getName(), enumerator.getLiteral()); - else - id = constructEnumID("unkownPackage URI", enumerator.getClass().getSimpleName(), - enumerator.getLiteral()); - - // generated enum should pre-empt the ecore enum literal as canonical enumerator - if (!uniqueIDToCanonicalEnumerator.containsKey(id)) { - uniqueIDToCanonicalEnumerator.put(id, enumerator); - } - } - uniqueIDFromEnumerator.put(enumerator, id); - uniqueIDToEnumerator.addPair(id, enumerator); - } - return id; - } - - protected String constructEnumID(String nsURI, String name, String literal) { - return String.format("%s##%s##%s", nsURI, name, literal); - } - - protected Object toKey(final EStructuralFeature feature) { - if (isDynamicModel) { - String id = uniqueIDFromTypedElement.get(feature); - if (id == null) { - Preconditions.checkArgument(!feature.eIsProxy(), - "Element %s is an unresolved proxy", feature); - id = toKeyDynamicInternal((EClassifier) feature.eContainer()) + "##" + feature.getEType().getName() - + "##" + feature.getName(); - uniqueIDFromTypedElement.put(feature, id); - uniqueIDToTypedElement.addPair(id, feature); - // metamodel maintenance will call back toKey(), but now the ID maps are already filled - maintainMetamodel(feature); - } - return id; - } else { - maintainMetamodel(feature); - return feature; - } - } - - protected Enumerator enumToCanonicalDynamicInternal(final Enumerator value) { - final String key = enumToKeyDynamicInternal(value); - Enumerator canonicalEnumerator = uniqueIDToCanonicalEnumerator.computeIfAbsent(key, - // if no canonical version appointed yet, appoint first version - k -> uniqueIDToEnumerator.lookup(k).iterator().next()); - return canonicalEnumerator; - } - - /** - * If in dynamic EMF mode, substitutes enum literals with a canonical version of the enum literal. - */ - protected Object toInternalValueRepresentation(final Object value) { - if (isDynamicModel) { - if (value instanceof Enumerator) - return enumToCanonicalDynamicInternal((Enumerator) value); - else - return value; - } else { - return value; - } - } - - /** - * Checks the {@link EStructuralFeature}'s source and target {@link EPackage} for NsURI collision. An error message - * will be logged if a model element from an other {@link EPackage} instance with the same NsURI has been already - * processed. The error message will be logged only for the first time for a given {@link EPackage} instance. - * - * @param classifier - * the classifier instance - */ - protected void maintainMetamodel(final EStructuralFeature feature) { - if (!knownFeatures.contains(feature)) { - knownFeatures.add(feature); - maintainMetamodel(feature.getEContainingClass()); - maintainMetamodel(feature.getEType()); - } - } - - /** - * put subtype information into cache - */ - protected void maintainMetamodel(final EClassifier classifier) { - if (!knownClassifiers.contains(classifier)) { - checkEPackage(classifier); - knownClassifiers.add(classifier); - - if (classifier instanceof EClass) { - final EClass clazz = (EClass) classifier; - final Object clazzKey = toKey(clazz); - for (final EClass superType : clazz.getEAllSuperTypes()) { - maintainTypeHierarhyInternal(clazzKey, toKey(superType)); - } - maintainTypeHierarhyInternal(clazzKey, getEObjectClassKey()); - } else if (classifier instanceof EEnum) { - EEnum eEnum = (EEnum) classifier; - - if (isDynamicModel) { - // if there is a generated enum class, save this model element for describing that class - if (eEnum.getInstanceClass() != null) - generatedEENumClasses.put(eEnum.getInstanceClass(), eEnum); - - for (EEnumLiteral eEnumLiteral : eEnum.getELiterals()) { - // create string ID; register generated enum values - enumToKeyDynamicInternal(eEnumLiteral); - } - } - } - } - } - - /** - * Checks the {@link EClassifier}'s {@link EPackage} for NsURI collision. An error message will be logged if a model - * element from an other {@link EPackage} instance with the same NsURI has been already processed. The error message - * will be logged only for the first time for a given {@link EPackage} instance. - * - * @param classifier - * the classifier instance - */ - protected void checkEPackage(final EClassifier classifier) { - final EPackage ePackage = classifier.getEPackage(); - if (knownPackages.add(ePackage)) { // this is a new EPackage - final String nsURI = ePackage.getNsURI(); - final IMemoryView packagesOfURI = uniqueIDToPackage.lookupOrEmpty(nsURI); - if (!packagesOfURI.containsNonZero(ePackage)) { // this should be true - uniqueIDToPackage.addPair(nsURI, ePackage); - // collision detection between EPackages (disabled in dynamic model mode) - if (!isDynamicModel && packagesOfURI.size() == 2) { // only report the issue if the new EPackage - // instance is the second for the same URI - navigationHelper.processingError( - new ViatraBaseException("NsURI (" + nsURI - + ") collision detected between different instances of EPackages. If this is normal, try using dynamic EMF mode."), - "process new metamodel elements."); - } - } - } - } - - /** - * Maintains subtype hierarchy - * - * @param subClassKey - * EClass or String id of subclass - * @param superClassKey - * EClass or String id of superclass - */ - protected void maintainTypeHierarhyInternal(final Object subClassKey, final Object superClassKey) { - // update observed class and instance listener tables according to new subtype information - Map allObservedClasses = navigationHelper.getAllObservedClassesInternal(); - if (allObservedClasses.containsKey(superClassKey)) { - // we know that there are no known subtypes of subClassKey at this point, so a single insert should suffice - allObservedClasses.put(subClassKey, allObservedClasses.get(superClassKey)); - } - final Map>> instanceListeners = navigationHelper.peekInstanceListeners(); - if (instanceListeners != null) { // table already constructed - for (final Entry> entry : instanceListeners.getOrDefault(superClassKey, Collections.emptyMap()).entrySet()) { - final InstanceListener listener = entry.getKey(); - for (final EClass subscriptionType : entry.getValue()) { - navigationHelper.addInstanceListenerInternal(listener, subscriptionType, subClassKey); - } - } - } - - // update subtype maps - Set subTypes = subTypeMap.computeIfAbsent(superClassKey, k -> new HashSet<>()); - subTypes.add(subClassKey); - Set superTypes = superTypeMap.computeIfAbsent(subClassKey, k -> new HashSet<>()); - superTypes.add(superClassKey); - } - - /** - * @return the subTypeMap - */ - protected Map> getSubTypeMap() { - return subTypeMap; - } - - protected Map> getSuperTypeMap() { - return superTypeMap; - } - - /** - * Returns the corresponding {@link EStructuralFeature} instance for the id. - * - * @param featureId - * the id of the feature - * @return the {@link EStructuralFeature} instance - */ - public EStructuralFeature getKnownFeature(final String featureId) { - final IMemoryView features = uniqueIDToTypedElement.lookup(featureId); - if (features != null && !features.isEmpty()) { - final ETypedElement next = features.iterator().next(); - if (next instanceof EStructuralFeature) { - return (EStructuralFeature) next; - } - } - return null; - - } - - public EStructuralFeature getKnownFeatureForKey(Object featureKey) { - EStructuralFeature feature; - if (isDynamicModel) { - feature = getKnownFeature((String) featureKey); - } else { - feature = (EStructuralFeature) featureKey; - } - return feature; - } - - /** - * Returns the corresponding {@link EClassifier} instance for the id. - */ - public EClassifier getKnownClassifier(final String key) { - final IMemoryView classifiersOfThisID = uniqueIDToClassifier.lookup(key); - if (classifiersOfThisID != null && !classifiersOfThisID.isEmpty()) { - return classifiersOfThisID.iterator().next(); - } else { - return null; - } - } - - public EClassifier getKnownClassifierForKey(Object classifierKey) { - EClassifier cls; - if (isDynamicModel) { - cls = getKnownClassifier((String) classifierKey); - } else { - cls = (EClassifier) classifierKey; - } - return cls; - } - - -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/EMFBaseIndexStatisticsStore.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/EMFBaseIndexStatisticsStore.java deleted file mode 100644 index de66de78..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/EMFBaseIndexStatisticsStore.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Grill Balázs, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.core; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.log4j.Logger; -import org.eclipse.emf.ecore.EClassifier; -import org.eclipse.emf.ecore.EStructuralFeature; - -/** - * @author Grill Balázs - * @noextend This class is not intended to be subclassed by clients. - */ -public class EMFBaseIndexStatisticsStore extends AbstractBaseIndexStore { - - /** - * A common map is used to store instance/value statistics. The key can be an {@link EClassifier}, - * {@link EStructuralFeature} or a String ID. - */ - private final Map stats = new HashMap(); - - public EMFBaseIndexStatisticsStore(NavigationHelperImpl navigationHelper, Logger logger) { - super(navigationHelper, logger); - } - public void addFeature(Object element, Object feature){ - addInstance(feature); - } - - public void removeFeature(Object element, Object feature){ - removeInstance(feature); - } - - public void addInstance(Object key){ - Integer v = stats.get(key); - stats.put(key, v == null ? 1 : v+1); - } - - public void removeInstance(Object key){ - Integer v = stats.get(key); - if(v == null || v <= 0) { - navigationHelper.logIncidentStatRemoval(key); - return; - } - if (v.intValue() == 1){ - stats.remove(key); - }else{ - stats.put(key, v-1); - } - } - public int countInstances(Object key){ - Integer v = stats.get(key); - return v == null ? 0 : v.intValue(); - } - - public void removeType(Object key){ - stats.remove(key); - } - - public int countFeatures(Object feature) { - return countInstances(feature); - } - -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/EMFDataSource.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/EMFDataSource.java deleted file mode 100644 index 35e590f2..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/EMFDataSource.java +++ /dev/null @@ -1,137 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.base.core; - -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EReference; -import tools.refinery.viatra.runtime.base.api.NavigationHelper; -import tools.refinery.viatra.runtime.base.itc.igraph.IGraphDataSource; -import tools.refinery.viatra.runtime.base.itc.igraph.IGraphObserver; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory; -import tools.refinery.viatra.runtime.matchers.util.IMemoryView; -import tools.refinery.viatra.runtime.matchers.util.IMultiset; - -// TODO IBiDirectionalGraphDataSource -public class EMFDataSource implements IGraphDataSource { - - private List> observers; - private Set references; - private Set classes; - private NavigationHelper navigationHelper; - private IMultiset allEObjects; // contains objects even if only appearing as sources or targets - - /** - * @param navigationHelper - * @param references - * @param classes - * additional classes to treat as nodes. Source and target classes of references need not be added. - */ - public EMFDataSource(NavigationHelper navigationHelper, Set references, Set classes) { - this.references = references; - this.classes = classes; - this.observers = new LinkedList>(); - this.navigationHelper = navigationHelper; - } - - @Override - public Set getAllNodes() { - return getAllEObjects().distinctValues(); - } - - @Override - public IMemoryView getTargetNodes(EObject source) { - IMultiset targetNodes = CollectionsFactory.createMultiset(); - - for (EReference ref : references) { - final Set referenceValues = navigationHelper.getReferenceValues(source, ref); - for (EObject referenceValue : referenceValues) { - targetNodes.addOne(referenceValue); - } - } - - return targetNodes; - } - - @Override - public void attachObserver(IGraphObserver go) { - observers.add(go); - } - - @Override - public void attachAsFirstObserver(IGraphObserver observer) { - observers.add(0, observer); - } - - @Override - public void detachObserver(IGraphObserver go) { - observers.remove(go); - } - - public void notifyEdgeInserted(EObject source, EObject target) { - nodeAdditionInternal(source); - nodeAdditionInternal(target); - for (IGraphObserver o : observers) { - o.edgeInserted(source, target); - } - } - - public void notifyEdgeDeleted(EObject source, EObject target) { - for (IGraphObserver o : observers) { - o.edgeDeleted(source, target); - } - nodeRemovalInternal(source); - nodeRemovalInternal(target); - } - - public void notifyNodeInserted(EObject node) { - nodeAdditionInternal(node); - } - - public void notifyNodeDeleted(EObject node) { - nodeRemovalInternal(node); - } - - private void nodeAdditionInternal(EObject node) { - if (allEObjects.addOne(node)) - for (IGraphObserver o : observers) { - o.nodeInserted(node); - } - } - - private void nodeRemovalInternal(EObject node) { - if (getAllEObjects().removeOne(node)) - for (IGraphObserver o : observers) { - o.nodeDeleted(node); - } - } - - protected IMultiset getAllEObjects() { - if (allEObjects == null) { - allEObjects = CollectionsFactory.createMultiset(); - for (EClass clazz : classes) { - for (EObject obj : navigationHelper.getAllInstances(clazz)) { - allEObjects.addOne(obj); - } - } - for (EReference ref : references) { - navigationHelper.processAllFeatureInstances(ref, (source, target) -> { - allEObjects.addOne(source); - allEObjects.addOne((EObject) target); - }); - } - } - return allEObjects; - } -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperContentAdapter.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperContentAdapter.java deleted file mode 100644 index 39271c5b..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperContentAdapter.java +++ /dev/null @@ -1,750 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - * - * Note: this file contains methods copied from EContentAdapter.java of the EMF project - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.core; - -import java.lang.reflect.InvocationTargetException; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.Callable; - -import org.eclipse.emf.common.notify.Adapter; -import org.eclipse.emf.common.notify.Notification; -import org.eclipse.emf.common.notify.Notifier; -import org.eclipse.emf.common.notify.impl.AdapterImpl; -import org.eclipse.emf.common.util.EList; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.InternalEObject; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.emf.ecore.util.EContentAdapter; -import tools.refinery.viatra.runtime.base.api.BaseIndexOptions; -import tools.refinery.viatra.runtime.base.api.filters.IBaseIndexObjectFilter; -import tools.refinery.viatra.runtime.base.api.filters.IBaseIndexResourceFilter; -import tools.refinery.viatra.runtime.base.comprehension.EMFModelComprehension; -import tools.refinery.viatra.runtime.base.comprehension.EMFVisitor; -import tools.refinery.viatra.runtime.base.core.NavigationHelperVisitor.ChangeVisitor; - -/** - * Content Adapter that recursively attaches itself to the containment hierarchy of an EMF model. - * The purpose is to gather the contents of the model, and to subscribe to model change notifications. - * - *

Originally, this was implemented as a subclass of {@link EContentAdapter}. - * Because of Bug 490105, EContentAdapter is no longer a superclass; its code is copied over with modifications. - * See {@link EContentAdapter} header for original authorship and copyright information. - * - * @author Gabor Bergmann - * @see EContentAdapter - * @noextend This class is not intended to be subclassed by clients. - */ -public class NavigationHelperContentAdapter extends AdapterImpl { - - private final NavigationHelperImpl navigationHelper; - - - - // move optimization to avoid removing and re-adding entire subtrees - EObject ignoreInsertionAndDeletion; - // Set ignoreRootInsertion = new HashSet(); - // Set ignoreRootDeletion = new HashSet(); - - private final EMFModelComprehension comprehension; - - private IBaseIndexObjectFilter objectFilterConfiguration; - private IBaseIndexResourceFilter resourceFilterConfiguration; - - - - private EMFVisitor removalVisitor; - private EMFVisitor insertionVisitor; - - public NavigationHelperContentAdapter(final NavigationHelperImpl navigationHelper) { - this.navigationHelper = navigationHelper; - final BaseIndexOptions options = this.navigationHelper.getBaseIndexOptions(); - objectFilterConfiguration = options.getObjectFilterConfiguration(); - resourceFilterConfiguration = options.getResourceFilterConfiguration(); - this.comprehension = navigationHelper.getComprehension(); - - removalVisitor = initChangeVisitor(false); - insertionVisitor = initChangeVisitor(true); - } - - /** - * Point of customization, called by constructor. - */ - protected ChangeVisitor initChangeVisitor(boolean isInsertion) { - return new NavigationHelperVisitor.ChangeVisitor(navigationHelper, isInsertion); - } - - // key representative of the EObject class - - - @Override - public void notifyChanged(final Notification notification) { - try { - this.navigationHelper.coalesceTraversals(new Callable() { - @Override - public Void call() throws Exception { - simpleNotifyChanged(notification); - - final Object oFeature = notification.getFeature(); - final Object oNotifier = notification.getNotifier(); - if (oNotifier instanceof EObject && oFeature instanceof EStructuralFeature) { - final EObject notifier = (EObject) oNotifier; - final EStructuralFeature feature = (EStructuralFeature) oFeature; - - final boolean notifyLightweightObservers = handleNotification(notification, notifier, feature); - - if (notifyLightweightObservers) { - navigationHelper.notifyLightweightObservers(notifier, feature, notification); - } - } else if (oNotifier instanceof Resource) { - if (notification.getFeatureID(Resource.class) == Resource.RESOURCE__IS_LOADED) { - final Resource resource = (Resource) oNotifier; - if (comprehension.isLoading(resource)) - navigationHelper.resolutionDelayingResources.add(resource); - else - navigationHelper.resolutionDelayingResources.remove(resource); - } - } - return null; - } - }); - } catch (final InvocationTargetException ex) { - navigationHelper.processingFatal(ex.getCause(), "handling the following update notification: " + notification); - } catch (final Exception ex) { - navigationHelper.processingFatal(ex, "handling the following update notification: " + notification); - } - - navigationHelper.notifyBaseIndexChangeListeners(); - } - - @SuppressWarnings("deprecation") - protected boolean handleNotification(final Notification notification, final EObject notifier, - final EStructuralFeature feature) { - final Object oldValue = notification.getOldValue(); - final Object newValue = notification.getNewValue(); - final int positionInt = notification.getPosition(); - final Integer position = positionInt == Notification.NO_INDEX ? null : positionInt; - final int eventType = notification.getEventType(); - boolean notifyLightweightObservers = true; - switch (eventType) { - case Notification.ADD: - featureUpdate(true, notifier, feature, newValue, position); - break; - case Notification.ADD_MANY: - for (final Object newElement : (Collection) newValue) { - featureUpdate(true, notifier, feature, newElement, position); - } - break; - case Notification.CREATE: - notifyLightweightObservers = false; - break; - case Notification.MOVE: - // lightweight observers should be notified on MOVE - break; // currently no support for ordering - case Notification.REMOVE: - featureUpdate(false, notifier, feature, oldValue, position); - break; - case Notification.REMOVE_MANY: - for (final Object oldElement : (Collection) oldValue) { - featureUpdate(false, notifier, feature, oldElement, position); - } - break; - case Notification.REMOVING_ADAPTER: - notifyLightweightObservers = false; - break; - case Notification.RESOLVE: // must be EReference - if (navigationHelper.isFeatureResolveIgnored(feature)) - break; // otherwise same as SET - if (!feature.isMany()) { // if single-valued, can be removed from delayed resolutions - navigationHelper.delayedProxyResolutions.removePairOrNop(notifier, (EReference) feature); - } - featureUpdate(false, notifier, feature, oldValue, position); - featureUpdate(true, notifier, feature, newValue, position); - break; - case Notification.UNSET: - case Notification.SET: - if(feature.isMany() && position == null){ - // spurious UNSET notification of entire collection - notifyLightweightObservers = false; - } else { - featureUpdate(false, notifier, feature, oldValue, position); - featureUpdate(true, notifier, feature, newValue, position); - } - break; - default: - notifyLightweightObservers = false; - break; - } - return notifyLightweightObservers; - } - - protected void featureUpdate(final boolean isInsertion, final EObject notifier, final EStructuralFeature feature, - final Object value, final Integer position) { - // this is a safe visitation, no reads will happen, thus no danger of notifications or matcher construction - comprehension.traverseFeature(getVisitorForChange(isInsertion), notifier, feature, value, position); - } - - // OFFICIAL ENTRY POINT OF BASE INDEX RELATED PARTS - protected void addAdapter(final Notifier notifier) { - if (notifier == ignoreInsertionAndDeletion) { - return; - } - try { - // cross-resource containment workaround, see Bug 483089 and Bug 483086. - if (notifier.eAdapters().contains(this)) - return; - - if (objectFilterConfiguration != null && objectFilterConfiguration.isFiltered(notifier)) { - return; - } - this.navigationHelper.coalesceTraversals(new Callable() { - @Override - public Void call() throws Exception { - // the object is really traversed BEFORE the notification listener is added, - // so that if a proxy is resolved due to the traversal, we do not get notified about it - if (notifier instanceof EObject) { - comprehension.traverseObject(getVisitorForChange(true), (EObject) notifier); - } else if (notifier instanceof Resource) { - Resource resource = (Resource) notifier; - if (resourceFilterConfiguration != null - && resourceFilterConfiguration.isResourceFiltered(resource)) { - return null; - } - if (comprehension.isLoading(resource)) - navigationHelper.resolutionDelayingResources.add(resource); - } - // subscribes to the adapter list, will receive setTarget callback that will spread addAdapter to - // children - simpleAddAdapter(notifier); - return null; - } - }); - } catch (final InvocationTargetException ex) { - navigationHelper.processingFatal(ex.getCause(), "add the object: " + notifier); - } catch (final Exception ex) { - navigationHelper.processingFatal(ex, "add the object: " + notifier); - } - } - - // OFFICIAL ENTRY POINT OF BASE INDEX RELATED PARTS - protected void removeAdapter(final Notifier notifier) { - if (notifier == ignoreInsertionAndDeletion) { - return; - } - try { - removeAdapterInternal(notifier); - } catch (final InvocationTargetException ex) { - navigationHelper.processingFatal(ex.getCause(), "remove the object: " + notifier); - } catch (final Exception ex) { - navigationHelper.processingFatal(ex, "remove the object: " + notifier); - } - } - - // The additional boolean options are there to save the cost of extra checks, see Bug 483089 and Bug 483086. - protected void removeAdapter(final Notifier notifier, boolean additionalObjectContainerPossible, - boolean additionalResourceContainerPossible) { - if (notifier == ignoreInsertionAndDeletion) { - return; - } - try { - - // cross-resource containment workaround, see Bug 483089 and Bug 483086. - if (notifier instanceof InternalEObject) { - InternalEObject internalEObject = (InternalEObject) notifier; - if (additionalResourceContainerPossible) { - Resource eDirectResource = internalEObject.eDirectResource(); - if (eDirectResource != null && eDirectResource.eAdapters().contains(this)) { - return; - } - } - if (additionalObjectContainerPossible) { - InternalEObject eInternalContainer = internalEObject.eInternalContainer(); - if (eInternalContainer != null && eInternalContainer.eAdapters().contains(this)) { - return; - } - } - } - - removeAdapterInternal(notifier); - } catch (final InvocationTargetException ex) { - navigationHelper.processingFatal(ex.getCause(), "remove the object: " + notifier); - } catch (final Exception ex) { - navigationHelper.processingFatal(ex, "remove the object: " + notifier); - } - } - - /** - * @throws InvocationTargetException - */ - protected void removeAdapterInternal(final Notifier notifier) throws InvocationTargetException { - // some non-standard EMF implementations send these - if (!notifier.eAdapters().contains(this)) { - // the adapter was not even attached to the notifier - navigationHelper.logIncidentAdapterRemoval(notifier); - - // skip the rest of the method, do not traverse contents - // as they have either never been added to the index or already removed - return; - } - - if (objectFilterConfiguration != null && objectFilterConfiguration.isFiltered(notifier)) { - return; - } - this.navigationHelper.coalesceTraversals(new Callable() { - @Override - public Void call() throws Exception { - if (notifier instanceof EObject) { - final EObject eObject = (EObject) notifier; - comprehension.traverseObject(getVisitorForChange(false), eObject); - navigationHelper.delayedProxyResolutions.lookupAndRemoveAll(eObject); - } else if (notifier instanceof Resource) { - if (resourceFilterConfiguration != null - && resourceFilterConfiguration.isResourceFiltered((Resource) notifier)) { - return null; - } - navigationHelper.resolutionDelayingResources.remove(notifier); - } - // unsubscribes from the adapter list, will receive unsetTarget callback that will spread - // removeAdapter to children - simpleRemoveAdapter(notifier); - return null; - } - }); - } - - protected EMFVisitor getVisitorForChange(final boolean isInsertion) { - return isInsertion ? insertionVisitor : removalVisitor; - } - - - // WORKAROUND (TMP) for eContents vs. derived features bug - protected void setTarget(final EObject target) { - basicSetTarget(target); - spreadToChildren(target, true); - } - - protected void unsetTarget(final EObject target) { - basicUnsetTarget(target); - spreadToChildren(target, false); - } - - // Spread adapter removal/addition to children of EObject - protected void spreadToChildren(final EObject target, final boolean add) { - final EList features = target.eClass().getEAllReferences(); - for (final EReference feature : features) { - if (!feature.isContainment()) { - continue; - } - if (!comprehension.representable(feature)) { - continue; - } - if (feature.isMany()) { - final Collection values = (Collection) target.eGet(feature); - for (final Object value : values) { - final Notifier notifier = (Notifier) value; - if (add) { - addAdapter(notifier); - } else { - removeAdapter(notifier, false, true); - } - } - } else { - final Object value = target.eGet(feature); - if (value != null) { - final Notifier notifier = (Notifier) value; - if (add) { - addAdapter(notifier); - } else { - removeAdapter(notifier, false, true); - } - } - } - } - } - - - // - // *********************************************************** - // RENAMED METHODS COPIED OVER FROM EContentAdapter DOWN BELOW - // *********************************************************** - // - - /** - * Handles a notification by calling {@link #selfAdapt selfAdapter}. - */ - public void simpleNotifyChanged(Notification notification) - { - selfAdapt(notification); - - super.notifyChanged(notification); - } - - protected void simpleAddAdapter(Notifier notifier) - { - EList eAdapters = notifier.eAdapters(); - if (!eAdapters.contains(this)) - { - eAdapters.add(this); - } - } - - protected void simpleRemoveAdapter(Notifier notifier) - { - notifier.eAdapters().remove(this); - } - - - // - // ********************************************************* - // CODE COPIED OVER VERBATIM FROM EContentAdapter DOWN BELOW - // ********************************************************* - // - - - /** - * Handles a notification by calling {@link #handleContainment handleContainment} - * for any containment-based notification. - */ - protected void selfAdapt(Notification notification) - { - Object notifier = notification.getNotifier(); - if (notifier instanceof ResourceSet) - { - if (notification.getFeatureID(ResourceSet.class) == ResourceSet.RESOURCE_SET__RESOURCES) - { - handleContainment(notification); - } - } - else if (notifier instanceof Resource) - { - if (notification.getFeatureID(Resource.class) == Resource.RESOURCE__CONTENTS) - { - handleContainment(notification); - } - } - else if (notifier instanceof EObject) - { - Object feature = notification.getFeature(); - if (feature instanceof EReference) - { - EReference eReference = (EReference)feature; - if (eReference.isContainment()) - { - handleContainment(notification); - } - } - } - } - - /** - * Handles a containment change by adding and removing the adapter as appropriate. - */ - protected void handleContainment(Notification notification) - { - switch (notification.getEventType()) - { - case Notification.RESOLVE: - { - // We need to be careful that the proxy may be resolved while we are attaching this adapter. - // We need to avoid attaching the adapter during the resolve - // and also attaching it again as we walk the eContents() later. - // Checking here avoids having to check during addAdapter. - // - Notifier oldValue = (Notifier)notification.getOldValue(); - if (oldValue.eAdapters().contains(this)) - { - removeAdapter(oldValue); - Notifier newValue = (Notifier)notification.getNewValue(); - addAdapter(newValue); - } - break; - } - case Notification.UNSET: - { - Object oldValue = notification.getOldValue(); - if (!Objects.equals(oldValue, Boolean.TRUE) && !Objects.equals(oldValue, Boolean.FALSE)) - { - if (oldValue != null) - { - removeAdapter((Notifier)oldValue, false, true); - } - Notifier newValue = (Notifier)notification.getNewValue(); - if (newValue != null) - { - addAdapter(newValue); - } - } - break; - } - case Notification.SET: - { - Notifier oldValue = (Notifier)notification.getOldValue(); - if (oldValue != null) - { - removeAdapter(oldValue, false, true); - } - Notifier newValue = (Notifier)notification.getNewValue(); - if (newValue != null) - { - addAdapter(newValue); - } - break; - } - case Notification.ADD: - { - Notifier newValue = (Notifier)notification.getNewValue(); - if (newValue != null) - { - addAdapter(newValue); - } - break; - } - case Notification.ADD_MANY: - { - @SuppressWarnings("unchecked") Collection newValues = (Collection)notification.getNewValue(); - for (Notifier newValue : newValues) - { - addAdapter(newValue); - } - break; - } - case Notification.REMOVE: - { - Notifier oldValue = (Notifier)notification.getOldValue(); - if (oldValue != null) - { - boolean checkContainer = notification.getNotifier() instanceof Resource; - boolean checkResource = notification.getFeature() != null; - removeAdapter(oldValue, checkContainer, checkResource); - } - break; - } - case Notification.REMOVE_MANY: - { - boolean checkContainer = notification.getNotifier() instanceof Resource; - boolean checkResource = notification.getFeature() != null; - @SuppressWarnings("unchecked") Collection oldValues = (Collection)notification.getOldValue(); - for ( Notifier oldContentValue : oldValues) - { - removeAdapter(oldContentValue, checkContainer, checkResource); - } - break; - } - } - } - - /** - * Handles installation of the adapter - * by adding the adapter to each of the directly contained objects. - */ - @Override - public void setTarget(Notifier target) - { - if (target instanceof EObject) - { - setTarget((EObject)target); - } - else if (target instanceof Resource) - { - setTarget((Resource)target); - } - else if (target instanceof ResourceSet) - { - setTarget((ResourceSet)target); - } - else - { - basicSetTarget(target); - } - } - - /** - * Actually sets the target by calling super. - */ - protected void basicSetTarget(Notifier target) - { - super.setTarget(target); - } - - /** - * Handles installation of the adapter on a Resource - * by adding the adapter to each of the directly contained objects. - */ - protected void setTarget(Resource target) - { - basicSetTarget(target); - List contents = target.getContents(); - for (int i = 0, size = contents.size(); i < size; ++i) - { - Notifier notifier = contents.get(i); - addAdapter(notifier); - } - } - - /** - * Handles installation of the adapter on a ResourceSet - * by adding the adapter to each of the directly contained objects. - */ - protected void setTarget(ResourceSet target) - { - basicSetTarget(target); - List resources = target.getResources(); - for (int i = 0; i < resources.size(); ++i) - { - Notifier notifier = resources.get(i); - addAdapter(notifier); - } - } - - /** - * Handles undoing the installation of the adapter - * by removing the adapter from each of the directly contained objects. - */ - @Override - public void unsetTarget(Notifier target) - { - Object target1 = target; - if (target1 instanceof EObject) - { - unsetTarget((EObject)target1); - } - else if (target1 instanceof Resource) - { - unsetTarget((Resource)target1); - } - else if (target1 instanceof ResourceSet) - { - unsetTarget((ResourceSet)target1); - } - else - { - basicUnsetTarget((Notifier)target1); - } - } - - /** - * Actually unsets the target by calling super. - */ - protected void basicUnsetTarget(Notifier target) - { - super.unsetTarget(target); - } - - /** - * Handles undoing the installation of the adapter from a Resource - * by removing the adapter from each of the directly contained objects. - */ - protected void unsetTarget(Resource target) - { - basicUnsetTarget(target); - List contents = target.getContents(); - for (int i = 0, size = contents.size(); i < size; ++i) - { - Notifier notifier = contents.get(i); - removeAdapter(notifier, true, false); - } - } - - /** - * Handles undoing the installation of the adapter from a ResourceSet - * by removing the adapter from each of the directly contained objects. - */ - protected void unsetTarget(ResourceSet target) - { - basicUnsetTarget(target); - List resources = target.getResources(); - for (int i = 0; i < resources.size(); ++i) - { - Notifier notifier = resources.get(i); - removeAdapter(notifier, false, false); - } - } - - protected boolean resolve() - { - return true; - } - - // - // ********************************************************* - // OBSOLETE CODE COPIED OVER FROM EContentAdapter DOWN BELOW - // ********************************************************* - // - // *** Preserved on purpose as comments, - // *** in order to more easily follow future changes to EContentAdapter. - // - - -// protected void removeAdapter(Notifier notifier, boolean checkContainer, boolean checkResource) -// { -// if (checkContainer || checkResource) -// { -// InternalEObject internalEObject = (InternalEObject) notifier; -// if (checkResource) -// { -// Resource eDirectResource = internalEObject.eDirectResource(); -// if (eDirectResource != null && eDirectResource.eAdapters().contains(this)) -// { -// return; -// } -// } -// if (checkContainer) -// { -// InternalEObject eInternalContainer = internalEObject.eInternalContainer(); -// if (eInternalContainer != null && eInternalContainer.eAdapters().contains(this)) -// { -// return; -// } -// } -// } -// -// removeAdapter(notifier); -// } - -// /** -// * Handles undoing the installation of the adapter from an EObject -// * by removing the adapter from each of the directly contained objects. -// */ -// protected void unsetTarget(EObject target) -// { -// basicUnsetTarget(target); -// for (Iterator i = resolve() ? -// target.eContents().iterator() : -// ((InternalEList)target.eContents()).basicIterator(); -// i.hasNext(); ) -// { -// Notifier notifier = i.next(); -// removeAdapter(notifier, false, true); -// } -// } - -// /** -// * Handles installation of the adapter on an EObject -// * by adding the adapter to each of the directly contained objects. -// */ -// protected void setTarget(EObject target) -// { -// basicSetTarget(target); -// for (Iterator i = resolve() ? -// target.eContents().iterator() : -// ((InternalEList)target.eContents()).basicIterator(); -// i.hasNext(); ) -// { -// Notifier notifier = i.next(); -// addAdapter(notifier); -// } -// } - -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperImpl.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperImpl.java deleted file mode 100644 index 2b5d74b5..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperImpl.java +++ /dev/null @@ -1,1702 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.core; - -import org.apache.log4j.Logger; -import org.eclipse.emf.common.notify.Notification; -import org.eclipse.emf.common.notify.Notifier; -import org.eclipse.emf.common.notify.NotifyingList; -import org.eclipse.emf.common.util.EList; -import org.eclipse.emf.ecore.*; -import org.eclipse.emf.ecore.EStructuralFeature.Setting; -import org.eclipse.emf.ecore.impl.ENotificationImpl; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.emf.ecore.util.EcoreUtil; -import tools.refinery.viatra.runtime.base.api.*; -import tools.refinery.viatra.runtime.base.api.IEClassifierProcessor.IEClassProcessor; -import tools.refinery.viatra.runtime.base.api.IEClassifierProcessor.IEDataTypeProcessor; -import tools.refinery.viatra.runtime.base.api.filters.IBaseIndexObjectFilter; -import tools.refinery.viatra.runtime.base.api.filters.IBaseIndexResourceFilter; -import tools.refinery.viatra.runtime.base.comprehension.EMFModelComprehension; -import tools.refinery.viatra.runtime.base.comprehension.EMFVisitor; -import tools.refinery.viatra.runtime.base.core.EMFBaseIndexInstanceStore.FeatureData; -import tools.refinery.viatra.runtime.base.core.NavigationHelperVisitor.TraversingVisitor; -import tools.refinery.viatra.runtime.base.core.profiler.ProfilingNavigationHelperContentAdapter; -import tools.refinery.viatra.runtime.base.exception.ViatraBaseException; -import tools.refinery.viatra.runtime.matchers.ViatraQueryRuntimeException; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory.MemoryType; -import tools.refinery.viatra.runtime.matchers.util.IMultiLookup; -import tools.refinery.viatra.runtime.matchers.util.Preconditions; - -import java.lang.reflect.InvocationTargetException; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.Callable; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static java.util.function.Function.identity; - -/** - * @noextend This class is not intended to be subclassed by clients. - * @author Gabor Bergmann and Tamas Szabo - */ -public class NavigationHelperImpl implements NavigationHelper { - - /** - * This is never null. - */ - protected IndexingLevel wildcardMode; - - - protected Set modelRoots; - private boolean expansionAllowed; - private boolean traversalDescendsAlongCrossResourceContainment; - // protected NavigationHelperVisitor visitor; - protected NavigationHelperContentAdapter contentAdapter; - - protected final Logger logger; - - // type object or String id - protected Map directlyObservedClasses = new HashMap(); - // including subclasses; if null, must be recomputed - protected Map allObservedClasses = null; - protected Map observedDataTypes; - protected Map observedFeatures; - // ignore RESOLVE for these features, as they are just starting to be observed - see [428458] - protected Set ignoreResolveNotificationFeatures; - - /** - * Feature registration and model traversal is delayed while true - */ - protected boolean delayTraversals = false; - /** - * Classes (or String ID in dynamic mode) to be registered once the coalescing period is over - */ - protected Map delayedClasses = new HashMap<>(); - /** - * EStructuralFeatures (or String ID in dynamic mode) to be registered once the coalescing period is over - */ - protected Map delayedFeatures = new HashMap<>(); - /** - * EDataTypes (or String ID in dynamic mode) to be registered once the coalescing period is over - */ - protected Map delayedDataTypes = new HashMap<>(); - - /** - * Features per EObject to be resolved later (towards the end of a coalescing period when no Resources are loading) - */ - protected IMultiLookup delayedProxyResolutions = CollectionsFactory.createMultiLookup(Object.class, MemoryType.SETS, Object.class); - /** - * Reasources that are currently loading, implying the proxy resolution attempts should be delayed - */ - protected Set resolutionDelayingResources = new HashSet(); - - protected Queue traversalCallbacks = new LinkedList(); - - /** - * These global listeners will be called after updates. - */ - // private final Set afterUpdateCallbacks; - private final Set baseIndexChangeListeners; - private final Map> lightweightObservers; - - // These are the user subscriptions to notifications - private final Map> subscribedInstanceListeners; - private final Map> subscribedFeatureListeners; - private final Map> subscribedDataTypeListeners; - - // these are the internal notification tables - // (element Type or String id) -> listener -> (subscription types) - // if null, must be recomputed from subscriptions - // potentially multiple subscription types for each element type because (a) nsURI collisions, (b) multiple - // supertypes - private Map>> instanceListeners; - private Map>> featureListeners; - private Map>> dataTypeListeners; - - private final Set errorListeners; - private final BaseIndexOptions baseIndexOptions; - - private EMFModelComprehension comprehension; - - private boolean loggedRegistrationMessage = false; - - EMFBaseIndexMetaStore metaStore; - EMFBaseIndexInstanceStore instanceStore; - EMFBaseIndexStatisticsStore statsStore; - - Set setMinus(Collection a, Collection b) { - Set result = new HashSet(a); - result.removeAll(b); - return result; - } - - @SuppressWarnings("unchecked") - Set resolveAllInternal(Set a) { - if (a == null) - a = Collections.emptySet(); - Set result = new HashSet(); - for (T t : a) { - if (t.eIsProxy()) { - result.add((T) EcoreUtil.resolve(t, (ResourceSet) null)); - } else { - result.add(t); - } - } - return result; - } - - Set resolveClassifiersToKey(Set classes) { - Set resolveds = resolveAllInternal(classes); - Set result = new HashSet(); - for (EClassifier resolved : resolveds) { - result.add(toKey(resolved)); - } - return result; - } - - Set resolveFeaturesToKey(Set features) { - Set resolveds = resolveAllInternal(features); - Set result = new HashSet(); - for (EStructuralFeature resolved : resolveds) { - result.add(toKey(resolved)); - } - return result; - } - - @Override - public boolean isInWildcardMode() { - return isInWildcardMode(IndexingLevel.FULL); - } - - @Override - public boolean isInWildcardMode(IndexingLevel level) { - return wildcardMode.providesLevel(level); - } - - @Override - public boolean isInDynamicEMFMode() { - return baseIndexOptions.isDynamicEMFMode(); - } - - /** - * @return the baseIndexOptions - */ - public BaseIndexOptions getBaseIndexOptions() { - return baseIndexOptions.copy(); - } - - /** - * @return the comprehension - */ - public EMFModelComprehension getComprehension() { - return comprehension; - } - - /** - * @throws ViatraQueryRuntimeException - */ - public NavigationHelperImpl(Notifier emfRoot, BaseIndexOptions options, Logger logger) { - this.baseIndexOptions = options.copy(); - this.logger = logger; - assert (logger != null); - - this.comprehension = initModelComprehension(); - this.wildcardMode = baseIndexOptions.getWildcardLevel(); - this.subscribedInstanceListeners = new HashMap>(); - this.subscribedFeatureListeners = new HashMap>(); - this.subscribedDataTypeListeners = new HashMap>(); - this.lightweightObservers = CollectionsFactory.createMap(); - this.observedFeatures = new HashMap(); - this.ignoreResolveNotificationFeatures = new HashSet(); - this.observedDataTypes = new HashMap(); - - metaStore = initMetaStore(); - instanceStore = initInstanceStore(); - statsStore = initStatStore(); - - this.contentAdapter = initContentAdapter(); - this.baseIndexChangeListeners = new HashSet(); - this.errorListeners = new LinkedHashSet(); - - this.modelRoots = new HashSet(); - this.expansionAllowed = false; - this.traversalDescendsAlongCrossResourceContainment = false; - - if (emfRoot != null) { - addRootInternal(emfRoot); - } - - } - - @Override - public IndexingLevel getWildcardLevel() { - return wildcardMode; - } - - @Override - public void setWildcardLevel(final IndexingLevel level) { - try{ - IndexingLevel mergedLevel = NavigationHelperImpl.this.wildcardMode.merge(level); - if (mergedLevel != NavigationHelperImpl.this.wildcardMode){ - NavigationHelperImpl.this.wildcardMode = mergedLevel; - - // force traversal upon change of wildcard level - final NavigationHelperVisitor visitor = initTraversingVisitor( - Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap()); - coalesceTraversals(() -> traverse(visitor)); - } - } catch (InvocationTargetException ex) { - processingFatal(ex.getCause(), "Setting wildcard level: " + level); - } catch (Exception ex) { - processingFatal(ex, "Setting wildcard level: " + level); - } - } - - public NavigationHelperContentAdapter getContentAdapter() { - return contentAdapter; - } - - public Map getObservedFeaturesInternal() { - return observedFeatures; - } - - public boolean isFeatureResolveIgnored(EStructuralFeature feature) { - return ignoreResolveNotificationFeatures.contains(toKey(feature)); - } - - @Override - public void dispose() { - ensureNoListenersForDispose(); - for (Notifier root : modelRoots) { - contentAdapter.removeAdapter(root); - } - } - - @Override - public Set getDataTypeInstances(EDataType type) { - Object typeKey = toKey(type); - return Collections.unmodifiableSet(instanceStore.getDistinctDataTypeInstances(typeKey)); - } - - @Override - public boolean isInstanceOfDatatype(Object value, EDataType type) { - Object typeKey = toKey(type); - Set valMap = instanceStore.getDistinctDataTypeInstances(typeKey); - return valMap.contains(value); - } - - protected FeatureData featureData(EStructuralFeature feature) { - return instanceStore.getFeatureData(toKey(feature)); - } - - @Override - public Set findByAttributeValue(Object value_) { - Object value = toCanonicalValueRepresentation(value_); - return getSettingsForTarget(value); - } - - @Override - public Set findByAttributeValue(Object value_, Collection attributes) { - Object value = toCanonicalValueRepresentation(value_); - Set retSet = new HashSet(); - - for (EAttribute attr : attributes) { - for (EObject holder : featureData(attr).getDistinctHoldersOfValue(value)) { - retSet.add(new NavigationHelperSetting(attr, holder, value)); - } - } - - return retSet; - } - - @Override - public Set findByAttributeValue(Object value_, EAttribute attribute) { - Object value = toCanonicalValueRepresentation(value_); - final Set holders = featureData(attribute).getDistinctHoldersOfValue(value); - return Collections.unmodifiableSet(holders); - } - - @Override - public void processAllFeatureInstances(EStructuralFeature feature, IStructuralFeatureInstanceProcessor processor) { - featureData(feature).forEach(processor); - } - - @Override - public void processDirectInstances(EClass type, IEClassProcessor processor) { - Object typeKey = toKey(type); - processDirectInstancesInternal(type, processor, typeKey); - } - - @Override - public void processAllInstances(EClass type, IEClassProcessor processor) { - Object typeKey = toKey(type); - Set subTypes = metaStore.getSubTypeMap().get(typeKey); - if (subTypes != null) { - for (Object subTypeKey : subTypes) { - processDirectInstancesInternal(type, processor, subTypeKey); - } - } - processDirectInstancesInternal(type, processor, typeKey); - } - - @Override - public void processDataTypeInstances(EDataType type, IEDataTypeProcessor processor) { - Object typeKey = toKey(type); - for (Object value : instanceStore.getDistinctDataTypeInstances(typeKey)) { - processor.process(type, value); - } - } - - protected void processDirectInstancesInternal(EClass type, IEClassProcessor processor, Object typeKey) { - final Set instances = instanceStore.getInstanceSet(typeKey); - if (instances != null) { - for (EObject eObject : instances) { - processor.process(type, eObject); - } - } - } - - @Override - public Set getInverseReferences(EObject target) { - return getSettingsForTarget(target); - } - - protected Set getSettingsForTarget(Object target) { - Set retSet = new HashSet(); - for (Object featureKey : instanceStore.getFeatureKeysPointingTo(target)) { - Set holders = instanceStore.getFeatureData(featureKey).getDistinctHoldersOfValue(target); - for (EObject holder : holders) { - EStructuralFeature feature = metaStore.getKnownFeatureForKey(featureKey); - retSet.add(new NavigationHelperSetting(feature, holder, target)); - } - } - return retSet; - } - - @Override - public Set getInverseReferences(EObject target, Collection references) { - Set retSet = new HashSet<>(); - for (EReference ref : references) { - final Set holders = featureData(ref).getDistinctHoldersOfValue(target); - for (EObject source : holders) { - retSet .add(new NavigationHelperSetting(ref, source, target)); - } - } - - return retSet; - } - - @Override - public Set getInverseReferences(EObject target, EReference reference) { - final Set holders = featureData(reference).getDistinctHoldersOfValue(target); - return Collections.unmodifiableSet(holders); - } - - @Override - @SuppressWarnings("unchecked") - public Set getReferenceValues(EObject source, EReference reference) { - Set targets = getFeatureTargets(source, reference); - return (Set) (Set) targets; // this is known to be safe, as EReferences can only point to EObjects - } - - @Override - public Set getFeatureTargets(EObject source, EStructuralFeature _feature) { - return Collections.unmodifiableSet(featureData(_feature).getDistinctValuesOfHolder(source)); - } - - @Override - public boolean isFeatureInstance(EObject source, Object target, EStructuralFeature _feature) { - return featureData(_feature).isInstance(source, target); - } - - @Override - public Set getDirectInstances(EClass type) { - Object typeKey = toKey(type); - Set valSet = instanceStore.getInstanceSet(typeKey); - if (valSet == null) { - return Collections.emptySet(); - } else { - return Collections.unmodifiableSet(valSet); - } - } - - protected Object toKey(EClassifier eClassifier) { - return metaStore.toKey(eClassifier); - } - - protected Object toKey(EStructuralFeature feature) { - return metaStore.toKey(feature); - } - - @Override - public Object toCanonicalValueRepresentation(Object value) { - return metaStore.toInternalValueRepresentation(value); - } - - @Override - public Set getAllInstances(EClass type) { - Set retSet = new HashSet(); - - Object typeKey = toKey(type); - Set subTypes = metaStore.getSubTypeMap().get(typeKey); - if (subTypes != null) { - for (Object subTypeKey : subTypes) { - final Set instances = instanceStore.getInstanceSet(subTypeKey); - if (instances != null) { - retSet.addAll(instances); - } - } - } - final Set instances = instanceStore.getInstanceSet(typeKey); - if (instances != null) { - retSet.addAll(instances); - } - - return retSet; - } - - @Override - public boolean isInstanceOfUnscoped(EObject object, EClass clazz) { - Object candidateTypeKey = toKey(clazz); - Object typeKey = toKey(object.eClass()); - - return doCalculateInstanceOf(candidateTypeKey, typeKey); - } - - @Override - public boolean isInstanceOfScoped(EObject object, EClass clazz) { - Object typeKey = toKey(object.eClass()); - if (!doCalculateInstanceOf(toKey(clazz), typeKey)) { - return false; - } - final Set instances = instanceStore.getInstanceSet(typeKey); - return instances != null && instances.contains(object); - } - - protected boolean doCalculateInstanceOf(Object candidateTypeKey, Object typeKey) { - if (candidateTypeKey.equals(typeKey)) return true; - if (metaStore.getEObjectClassKey().equals(candidateTypeKey)) return true; - - Set superTypes = metaStore.getSuperTypeMap().get(typeKey); - return superTypes.contains(candidateTypeKey); - } - - @Override - public Set findByFeatureValue(Object value_, EStructuralFeature _feature) { - Object value = toCanonicalValueRepresentation(value_); - return Collections.unmodifiableSet(featureData(_feature).getDistinctHoldersOfValue(value)); - } - - @Override - public Set getHoldersOfFeature(EStructuralFeature _feature) { - Object feature = toKey(_feature); - return Collections.unmodifiableSet(instanceStore.getHoldersOfFeature(feature)); - } - @Override - public Set getValuesOfFeature(EStructuralFeature _feature) { - Object feature = toKey(_feature); - return Collections.unmodifiableSet(instanceStore.getValuesOfFeature(feature)); - } - - @Override - public void addInstanceListener(Collection classes, InstanceListener listener) { - Set registered = this.subscribedInstanceListeners.computeIfAbsent(listener, l -> new HashSet<>()); - Set delta = setMinus(classes, registered); - if (!delta.isEmpty()) { - registered.addAll(delta); - if (instanceListeners != null) { // if already computed - for (EClass subscriptionType : delta) { - final Object superElementTypeKey = toKey(subscriptionType); - addInstanceListenerInternal(listener, subscriptionType, superElementTypeKey); - final Set subTypeKeys = metaStore.getSubTypeMap().get(superElementTypeKey); - if (subTypeKeys != null) - for (Object subTypeKey : subTypeKeys) { - addInstanceListenerInternal(listener, subscriptionType, subTypeKey); - } - } - } - } - } - - @Override - public void removeInstanceListener(Collection classes, InstanceListener listener) { - Set restriction = this.subscribedInstanceListeners.get(listener); - if (restriction != null) { - boolean changed = restriction.removeAll(classes); - if (restriction.size() == 0) { - this.subscribedInstanceListeners.remove(listener); - } - if (changed) - instanceListeners = null; // recompute later on demand - } - } - - @Override - public void addFeatureListener(Collection features, FeatureListener listener) { - Set registered = this.subscribedFeatureListeners.computeIfAbsent(listener, l -> new HashSet<>()); - Set delta = setMinus(features, registered); - if (!delta.isEmpty()) { - registered.addAll(delta); - if (featureListeners != null) { // if already computed - for (EStructuralFeature subscriptionType : delta) { - addFeatureListenerInternal(listener, subscriptionType, toKey(subscriptionType)); - } - } - } - } - - @Override - public void removeFeatureListener(Collection features, FeatureListener listener) { - Collection restriction = this.subscribedFeatureListeners.get(listener); - if (restriction != null) { - boolean changed = restriction.removeAll(features); - if (restriction.size() == 0) { - this.subscribedFeatureListeners.remove(listener); - } - if (changed) - featureListeners = null; // recompute later on demand - } - } - - @Override - public void addDataTypeListener(Collection types, DataTypeListener listener) { - Set registered = this.subscribedDataTypeListeners.computeIfAbsent(listener, l -> new HashSet<>()); - Set delta = setMinus(types, registered); - if (!delta.isEmpty()) { - registered.addAll(delta); - if (dataTypeListeners != null) { // if already computed - for (EDataType subscriptionType : delta) { - addDatatypeListenerInternal(listener, subscriptionType, toKey(subscriptionType)); - } - } - } - } - - @Override - public void removeDataTypeListener(Collection types, DataTypeListener listener) { - Collection restriction = this.subscribedDataTypeListeners.get(listener); - if (restriction != null) { - boolean changed = restriction.removeAll(types); - if (restriction.size() == 0) { - this.subscribedDataTypeListeners.remove(listener); - } - if (changed) - dataTypeListeners = null; // recompute later on demand - } - } - - /** - * @return the observedDataTypes - */ - public Map getObservedDataTypesInternal() { - return observedDataTypes; - } - - @Override - public boolean addLightweightEObjectObserver(LightweightEObjectObserver observer, EObject observedObject) { - Set observers = lightweightObservers.computeIfAbsent(observedObject, CollectionsFactory::emptySet); - return observers.add(observer); - } - - @Override - public boolean removeLightweightEObjectObserver(LightweightEObjectObserver observer, EObject observedObject) { - boolean result = false; - Set observers = lightweightObservers.get(observedObject); - if (observers != null) { - result = observers.remove(observer); - if (observers.isEmpty()) { - lightweightObservers.remove(observedObject); - } - } - return result; - } - - public void notifyBaseIndexChangeListeners() { - notifyBaseIndexChangeListeners(instanceStore.isDirty); - if (instanceStore.isDirty) { - instanceStore.isDirty = false; - } - } - - /** - * This will run after updates. - */ - protected void notifyBaseIndexChangeListeners(boolean baseIndexChanged) { - if (!baseIndexChangeListeners.isEmpty()) { - for (EMFBaseIndexChangeListener listener : new ArrayList<>(baseIndexChangeListeners)) { - try { - if (!listener.onlyOnIndexChange() || baseIndexChanged) { - listener.notifyChanged(baseIndexChanged); - } - } catch (Exception ex) { - notifyFatalListener("VIATRA Base encountered an error in delivering notifications about changes. ", - ex); - } - } - } - } - - void notifyDataTypeListeners(final Object typeKey, final Object value, final boolean isInsertion, - final boolean firstOrLastOccurrence) { - for (final Entry> entry : getDataTypeListeners().getOrDefault(typeKey, Collections.emptyMap()).entrySet()) { - final DataTypeListener listener = entry.getKey(); - for (final EDataType subscriptionType : entry.getValue()) { - if (isInsertion) { - listener.dataTypeInstanceInserted(subscriptionType, value, firstOrLastOccurrence); - } else { - listener.dataTypeInstanceDeleted(subscriptionType, value, firstOrLastOccurrence); - } - } - } - } - - void notifyFeatureListeners(final EObject host, final Object featureKey, final Object value, - final boolean isInsertion) { - for (final Entry> entry : getFeatureListeners().getOrDefault(featureKey, Collections.emptyMap()) - .entrySet()) { - final FeatureListener listener = entry.getKey(); - for (final EStructuralFeature subscriptionType : entry.getValue()) { - if (isInsertion) { - listener.featureInserted(host, subscriptionType, value); - } else { - listener.featureDeleted(host, subscriptionType, value); - } - } - } - } - - void notifyInstanceListeners(final Object clazzKey, final EObject instance, final boolean isInsertion) { - for (final Entry> entry : getInstanceListeners().getOrDefault(clazzKey, Collections.emptyMap()).entrySet()) { - final InstanceListener listener = entry.getKey(); - for (final EClass subscriptionType : entry.getValue()) { - if (isInsertion) { - listener.instanceInserted(subscriptionType, instance); - } else { - listener.instanceDeleted(subscriptionType, instance); - } - } - } - } - - void notifyLightweightObservers(final EObject host, final EStructuralFeature feature, - final Notification notification) { - if (lightweightObservers.containsKey(host)) { - Set observers = lightweightObservers.get(host); - for (final LightweightEObjectObserver observer : observers) { - observer.notifyFeatureChanged(host, feature, notification); - } - } - } - - @Override - public void addBaseIndexChangeListener(EMFBaseIndexChangeListener listener) { - Preconditions.checkArgument(listener != null, "Cannot add null listener!"); - baseIndexChangeListeners.add(listener); - } - - @Override - public void removeBaseIndexChangeListener(EMFBaseIndexChangeListener listener) { - Preconditions.checkArgument(listener != null, "Cannot remove null listener!"); - baseIndexChangeListeners.remove(listener); - } - - @Override - public boolean addIndexingErrorListener(IEMFIndexingErrorListener listener) { - return errorListeners.add(listener); - } - - @Override - public boolean removeIndexingErrorListener(IEMFIndexingErrorListener listener) { - return errorListeners.remove(listener); - } - - protected void processingFatal(final Throwable ex, final String task) { - notifyFatalListener(logTaskFormat(task), ex); - } - - protected void processingError(final Throwable ex, final String task) { - notifyErrorListener(logTaskFormat(task), ex); - } - - public void notifyErrorListener(String message, Throwable t) { - logger.error(message, t); - for (IEMFIndexingErrorListener listener : new ArrayList<>(errorListeners)) { - listener.error(message, t); - } - } - - public void notifyFatalListener(String message, Throwable t) { - logger.fatal(message, t); - for (IEMFIndexingErrorListener listener : new ArrayList<>(errorListeners)) { - listener.fatal(message, t); - } - } - - protected String logTaskFormat(final String task) { - return "VIATRA Query encountered an error in processing the EMF model. " + "This happened while trying to " - + task; - } - - protected void considerForExpansion(EObject obj) { - if (expansionAllowed) { - Resource eResource = obj.eResource(); - if (eResource != null && eResource.getResourceSet() == null) { - expandToAdditionalRoot(eResource); - } - } - } - - protected void expandToAdditionalRoot(Notifier root) { - if (modelRoots.contains(root)) - return; - - if (root instanceof ResourceSet) { - expansionAllowed = true; - } else if (root instanceof Resource) { - IBaseIndexResourceFilter resourceFilter = baseIndexOptions.getResourceFilterConfiguration(); - if (resourceFilter != null && resourceFilter.isResourceFiltered((Resource) root)) - return; - } else { // root instanceof EObject - traversalDescendsAlongCrossResourceContainment = true; - } - final IBaseIndexObjectFilter objectFilter = baseIndexOptions.getObjectFilterConfiguration(); - if (objectFilter != null && objectFilter.isFiltered(root)) - return; - - // no veto by filters - modelRoots.add(root); - contentAdapter.addAdapter(root); - notifyBaseIndexChangeListeners(); - } - - /** - * @return the expansionAllowed - */ - public boolean isExpansionAllowed() { - return expansionAllowed; - } - - public boolean traversalDescendsAlongCrossResourceContainment() { - return traversalDescendsAlongCrossResourceContainment; - } - - /** - * @return the directlyObservedClasses - */ - public Set getDirectlyObservedClassesInternal() { - return directlyObservedClasses.keySet(); - } - - boolean isObservedInternal(Object clazzKey) { - return isInWildcardMode() || getAllObservedClassesInternal().containsKey(clazzKey); - } - - /** - * Add the given item the map with the given indexing level if it wasn't already added with a higher level. - * @param level non-null - * @return whether actually changed - */ - protected static boolean putIntoMapMerged(Map map, V key, IndexingLevel level) { - IndexingLevel l = map.get(key); - IndexingLevel merged = level.merge(l); - if (merged != l) { - map.put(key, merged); - return true; - } else { - return false; - } - } - - /** - * @return true if actually changed - */ - protected boolean addObservedClassesInternal(Object eClassKey, IndexingLevel level) { - boolean changed = putIntoMapMerged(allObservedClasses, eClassKey, level); - if (!changed) return false; - - final Set subTypes = metaStore.getSubTypeMap().get(eClassKey); - if (subTypes != null) { - for (Object subType : subTypes) { - /* - * It is necessary to check if the class has already been added with a higher indexing level as in case - * of multiple inheritance, a subclass may be registered for statistics only but full indexing may be - * required via one of its super classes. - */ - putIntoMapMerged(allObservedClasses, subType, level); - } - } - return true; - } - - /** - * not just the directly observed classes, but also their known subtypes - */ - public Map getAllObservedClassesInternal() { - if (allObservedClasses == null) { - allObservedClasses = new HashMap(); - for (Entry entry : directlyObservedClasses.entrySet()) { - Object eClassKey = entry.getKey(); - IndexingLevel level = entry.getValue(); - addObservedClassesInternal(eClassKey, level); - } - } - return allObservedClasses; - } - - /** - * @return the instanceListeners - */ - Map>> getInstanceListeners() { - if (instanceListeners == null) { - instanceListeners = CollectionsFactory.createMap(); - for (Entry> subscription : subscribedInstanceListeners.entrySet()) { - final InstanceListener listener = subscription.getKey(); - for (EClass subscriptionType : subscription.getValue()) { - final Object superElementTypeKey = toKey(subscriptionType); - addInstanceListenerInternal(listener, subscriptionType, superElementTypeKey); - final Set subTypeKeys = metaStore.getSubTypeMap().get(superElementTypeKey); - if (subTypeKeys != null) - for (Object subTypeKey : subTypeKeys) { - addInstanceListenerInternal(listener, subscriptionType, subTypeKey); - } - } - } - } - return instanceListeners; - } - - Map>> peekInstanceListeners() { - return instanceListeners; - } - - void addInstanceListenerInternal(final InstanceListener listener, EClass subscriptionType, - final Object elementTypeKey) { - Set subscriptionTypes = instanceListeners - .computeIfAbsent(elementTypeKey, k -> CollectionsFactory.createMap()) - .computeIfAbsent(listener, k -> CollectionsFactory.createSet()); - subscriptionTypes.add(subscriptionType); - } - - /** - * @return the featureListeners - */ - Map>> getFeatureListeners() { - if (featureListeners == null) { - featureListeners = CollectionsFactory.createMap(); - for (Entry> subscription : subscribedFeatureListeners.entrySet()) { - final FeatureListener listener = subscription.getKey(); - for (EStructuralFeature subscriptionType : subscription.getValue()) { - final Object elementTypeKey = toKey(subscriptionType); - addFeatureListenerInternal(listener, subscriptionType, elementTypeKey); - } - } - } - return featureListeners; - } - - void addFeatureListenerInternal(final FeatureListener listener, EStructuralFeature subscriptionType, - final Object elementTypeKey) { - Set subscriptionTypes = featureListeners - .computeIfAbsent(elementTypeKey, k -> CollectionsFactory.createMap()) - .computeIfAbsent(listener, k -> CollectionsFactory.createSet()); - subscriptionTypes.add(subscriptionType); - } - - /** - * @return the dataTypeListeners - */ - Map>> getDataTypeListeners() { - if (dataTypeListeners == null) { - dataTypeListeners = CollectionsFactory.createMap(); - for (Entry> subscription : subscribedDataTypeListeners.entrySet()) { - final DataTypeListener listener = subscription.getKey(); - for (EDataType subscriptionType : subscription.getValue()) { - final Object elementTypeKey = toKey(subscriptionType); - addDatatypeListenerInternal(listener, subscriptionType, elementTypeKey); - } - } - } - return dataTypeListeners; - } - - void addDatatypeListenerInternal(final DataTypeListener listener, EDataType subscriptionType, - final Object elementTypeKey) { - Set subscriptionTypes = dataTypeListeners - .computeIfAbsent(elementTypeKey, k -> CollectionsFactory.createMap()) - .computeIfAbsent(listener, k -> CollectionsFactory.createSet()); - subscriptionTypes.add(subscriptionType); - } - - public void registerObservedTypes(Set classes, Set dataTypes, - Set features) { - registerObservedTypes(classes, dataTypes, features, IndexingLevel.FULL); - } - - @Override - public void registerObservedTypes(Set classes, Set dataTypes, - Set features, final IndexingLevel level) { - if (isRegistrationNecessary(level) && (classes != null || features != null || dataTypes != null)) { - final Set resolvedFeatures = resolveFeaturesToKey(features); - final Set resolvedClasses = resolveClassifiersToKey(classes); - final Set resolvedDatatypes = resolveClassifiersToKey(dataTypes); - - try { - coalesceTraversals(() -> { - Function f = input -> level; - delayedFeatures.putAll(resolvedFeatures.stream().collect(Collectors.toMap(identity(), f))); - delayedDataTypes.putAll(resolvedDatatypes.stream().collect(Collectors.toMap(identity(), f))); - delayedClasses.putAll(resolvedClasses.stream().collect(Collectors.toMap(identity(), f))); - }); - } catch (InvocationTargetException ex) { - processingFatal(ex.getCause(), "register en masse the observed EClasses " + resolvedClasses - + " and EDatatypes " + resolvedDatatypes + " and EStructuralFeatures " + resolvedFeatures); - } catch (Exception ex) { - processingFatal(ex, "register en masse the observed EClasses " + resolvedClasses + " and EDatatypes " - + resolvedDatatypes + " and EStructuralFeatures " + resolvedFeatures); - } - } - } - - @Override - public void unregisterObservedTypes(Set classes, Set dataTypes, - Set features) { - unregisterEClasses(classes); - unregisterEDataTypes(dataTypes); - unregisterEStructuralFeatures(features); - } - - @Override - public void registerEStructuralFeatures(Set features, final IndexingLevel level) { - if (isRegistrationNecessary(level) && features != null) { - final Set resolved = resolveFeaturesToKey(features); - - try { - coalesceTraversals(() -> resolved.forEach(o -> delayedFeatures.put(o, level))); - } catch (InvocationTargetException ex) { - processingFatal(ex.getCause(), "register the observed EStructuralFeatures: " + resolved); - } catch (Exception ex) { - processingFatal(ex, "register the observed EStructuralFeatures: " + resolved); - } - } - } - - @Override - public void unregisterEStructuralFeatures(Set features) { - if (isRegistrationNecessary(IndexingLevel.FULL) && features != null) { - final Set resolved = resolveFeaturesToKey(features); - ensureNoListeners(resolved, getFeatureListeners()); - observedFeatures.keySet().removeAll(resolved); - delayedFeatures.keySet().removeAll(resolved); - for (Object f : resolved) { - instanceStore.forgetFeature(f); - statsStore.removeType(f); - } - } - } - - @Override - public void registerEClasses(Set classes, final IndexingLevel level) { - if (isRegistrationNecessary(level) && classes != null) { - final Set resolvedClasses = resolveClassifiersToKey(classes); - - try { - coalesceTraversals(() -> resolvedClasses.forEach(o -> delayedClasses.put(o, level))); - } catch (InvocationTargetException ex) { - processingFatal(ex.getCause(), "register the observed EClasses: " + resolvedClasses); - } catch (Exception ex) { - processingFatal(ex, "register the observed EClasses: " + resolvedClasses); - } - } - } - - /** - * @return true if there is an actual change in the transitively computed observation levels, - * warranting an actual traversal - */ - protected boolean startObservingClasses(Map requestedClassObservations) { - boolean warrantsTraversal = false; - getAllObservedClassesInternal(); // pre-populate - for (Entry request : requestedClassObservations.entrySet()) { - if (putIntoMapMerged(directlyObservedClasses, request.getKey(), request.getValue())) { - // maybe already observed for the sake of a supertype? - if (addObservedClassesInternal(request.getKey(), request.getValue())) { - warrantsTraversal = true; - }; - } - } - return warrantsTraversal; - } - - @Override - public void unregisterEClasses(Set classes) { - if (isRegistrationNecessary(IndexingLevel.FULL) && classes != null) { - final Set resolved = resolveClassifiersToKey(classes); - ensureNoListeners(resolved, getInstanceListeners()); - directlyObservedClasses.keySet().removeAll(resolved); - allObservedClasses = null; - delayedClasses.keySet().removeAll(resolved); - for (Object c : resolved) { - instanceStore.removeInstanceSet(c); - statsStore.removeType(c); - } - } - } - - @Override - public void registerEDataTypes(Set dataTypes, final IndexingLevel level) { - if (isRegistrationNecessary(level) && dataTypes != null) { - final Set resolved = resolveClassifiersToKey(dataTypes); - - try { - coalesceTraversals(() -> resolved.forEach(o -> delayedDataTypes.put(o, level))); - } catch (InvocationTargetException ex) { - processingFatal(ex.getCause(), "register the observed EDataTypes: " + resolved); - } catch (Exception ex) { - processingFatal(ex, "register the observed EDataTypes: " + resolved); - } - } - } - - @Override - public void unregisterEDataTypes(Set dataTypes) { - if (isRegistrationNecessary(IndexingLevel.FULL) && dataTypes != null) { - final Set resolved = resolveClassifiersToKey(dataTypes); - ensureNoListeners(resolved, getDataTypeListeners()); - observedDataTypes.keySet().removeAll(resolved); - delayedDataTypes.keySet().removeAll(resolved); - for (Object dataType : resolved) { - instanceStore.removeDataTypeMap(dataType); - statsStore.removeType(dataType); - } - } - } - - @Override - public boolean isCoalescing() { - return delayTraversals; - } - - public void coalesceTraversals(final Runnable runnable) throws InvocationTargetException { - coalesceTraversals(() -> { - runnable.run(); - return null; - }); - } - - @Override - public V coalesceTraversals(Callable callable) throws InvocationTargetException { - V finalResult = null; - - if (delayTraversals) { // reentrant case, no special action needed - try { - finalResult = callable.call(); - } catch (Exception e) { - throw new InvocationTargetException(e); - } - return finalResult; - } - - boolean firstRun = true; - while (callable != null) { // repeat if post-processing needed - - try { - delayTraversals = true; - - V result = callable.call(); - if (firstRun) { - firstRun = false; - finalResult = result; - } - - // are there proxies left to be resolved? are we allowed to resolve them now? - while ((!delayedProxyResolutions.isEmpty()) && resolutionDelayingResources.isEmpty()) { - // pop first entry - EObject toResolveObject = delayedProxyResolutions.distinctKeys().iterator().next(); - EReference toResolveReference = delayedProxyResolutions.lookup(toResolveObject).iterator().next(); - delayedProxyResolutions.removePair(toResolveObject, toResolveReference); - - // see if we can resolve proxies - comprehension.tryResolveReference(toResolveObject, toResolveReference); - } - - delayTraversals = false; - callable = considerRevisit(); - } catch (Exception e) { - // since this is a fatal error, it is OK if delayTraversals remains true, - // hence no need for a try-finally block - - notifyFatalListener( - "VIATRA Base encountered an error while traversing the EMF model to gather new information. ", - e); - throw new InvocationTargetException(e); - } - } - executeTraversalCallbacks(); - return finalResult; - } - - protected Callable considerRevisit() { - // has there been any requests for a retraversal at all? - if (!delayedClasses.isEmpty() || !delayedFeatures.isEmpty() || !delayedDataTypes.isEmpty()) { - // make copies of requested types so that - // (a) original accumulators can be cleaned for the next cycle, also - // (b) to remove entries that are already covered, or - // (c) for the rare case that a coalesced traversal is invoked during visitation, - // e.g. by a derived feature implementation - // initialize the collections empty (but with capacity), fill with new entries - final Map toGatherClasses = new HashMap(delayedClasses.size()); - final Map toGatherFeatures = new HashMap(delayedFeatures.size()); - final Map toGatherDataTypes = new HashMap(delayedDataTypes.size()); - - for (Entry requested : delayedFeatures.entrySet()) { - Object typekey = requested.getKey(); - IndexingLevel old = observedFeatures.get(typekey); - IndexingLevel merged = requested.getValue().merge(old); - if (merged != old) toGatherFeatures.put(typekey, merged); - } - for (Entry requested : delayedClasses.entrySet()) { - Object typekey = requested.getKey(); - IndexingLevel old = directlyObservedClasses.get(typekey); - IndexingLevel merged = requested.getValue().merge(old); - if (merged != old) toGatherClasses.put(typekey, merged); - } - for (Entry requested : delayedDataTypes.entrySet()) { - Object typekey = requested.getKey(); - IndexingLevel old = observedDataTypes.get(typekey); - IndexingLevel merged = requested.getValue().merge(old); - if (merged != old) toGatherDataTypes.put(typekey, merged); - } - - delayedClasses.clear(); - delayedFeatures.clear(); - delayedDataTypes.clear(); - - // check if the filtered request sets are empty - // - could be false alarm if we already observe all of them - if (!toGatherClasses.isEmpty() || !toGatherFeatures.isEmpty() || !toGatherDataTypes.isEmpty()) { - final HashMap oldClasses = new HashMap( - directlyObservedClasses); - - /* Instance indexing would add extra entries to the statistics store, so we have to clean the - * appropriate entries. If no re-traversal is required, it is detected earlier; at this point we - * only have to consider the target indexing level. See bug - * https://bugs.eclipse.org/bugs/show_bug.cgi?id=518356 for more details. - * - * This has to be executed before the old observed types are updated to check whether the indexing level increased. - * - * Technically, the statsStore cleanup seems only necessary for EDataTypes; otherwise everything - * works as expected, but it seems a better idea to do the cleanup for all types in the same way */ - toGatherClasses.forEach((key, value) -> { - IndexingLevel oldIndexingLevel = getIndexingLevel(metaStore.getKnownClassifierForKey(key)); - if (value.hasInstances() && oldIndexingLevel.hasStatistics() && !oldIndexingLevel.hasInstances()) { - statsStore.removeType(key); - } - - }); - toGatherFeatures.forEach((key, value) -> { - IndexingLevel oldIndexingLevel = getIndexingLevel(metaStore.getKnownFeatureForKey(key)); - if (value.hasInstances() && oldIndexingLevel.hasStatistics() && !oldIndexingLevel.hasInstances()) { - statsStore.removeType(key); - } - - }); - toGatherDataTypes.forEach((key, value) -> { - IndexingLevel oldIndexingLevel = getIndexingLevel(metaStore.getKnownClassifierForKey(key)); - if (value.hasInstances() && oldIndexingLevel.hasStatistics() && !oldIndexingLevel.hasInstances()) { - statsStore.removeType(key); - } - - }); - - // Are there new classes to be observed that are not available via superclasses? - // (at sufficient level) - // if yes, model traversal needed - // if not, index can be updated without retraversal - boolean classesWarrantTraversal = startObservingClasses(toGatherClasses); - observedDataTypes.putAll(toGatherDataTypes); - observedFeatures.putAll(toGatherFeatures); - - - // So, is an actual traversal needed, or are we done? - if (classesWarrantTraversal || !toGatherFeatures.isEmpty() || !toGatherDataTypes.isEmpty()) { - // repeat the cycle with this visit - final NavigationHelperVisitor visitor = initTraversingVisitor(toGatherClasses, toGatherFeatures, toGatherDataTypes, oldClasses); - - return new Callable() { - @Override - public V call() throws Exception { - // temporarily ignoring RESOLVE on these features, as they were not observed before - ignoreResolveNotificationFeatures.addAll(toGatherFeatures.keySet()); - try { - traverse(visitor); - } finally { - ignoreResolveNotificationFeatures.removeAll(toGatherFeatures.keySet()); - } - return null; - } - }; - - } - } - } - - return null; // no callable -> no further action - } - - protected void executeTraversalCallbacks() throws InvocationTargetException{ - final Runnable[] callbacks = traversalCallbacks.toArray(new Runnable[traversalCallbacks.size()]); - traversalCallbacks.clear(); - if (callbacks.length > 0){ - coalesceTraversals(() -> Arrays.stream(callbacks).forEach(Runnable::run)); - } - } - - protected void traverse(final NavigationHelperVisitor visitor) { - // Cloning model roots avoids a concurrent modification exception - for (Notifier root : new HashSet(modelRoots)) { - comprehension.traverseModel(visitor, root); - } - notifyBaseIndexChangeListeners(); - } - - /** - * Returns a stream of model roots registered to the navigation helper instance - * @since 2.3 - */ - protected Stream getModelRoots() { - return modelRoots.stream(); - } - - @Override - public void addRoot(Notifier emfRoot) { - addRootInternal(emfRoot); - } - - /** - * Supports removing model roots - *

- * Note: for now this API is considered experimental thus it is not added to the {@link NavigationHelper} interface. - * @since 2.3 - */ - protected void removeRoot(Notifier root) { - if (!((root instanceof EObject) || (root instanceof Resource) || (root instanceof ResourceSet))) { - throw new ViatraBaseException(ViatraBaseException.INVALID_EMFROOT); - } - - if (!modelRoots.contains(root)) - return; - - if (root instanceof Resource) { - IBaseIndexResourceFilter resourceFilter = getBaseIndexOptions().getResourceFilterConfiguration(); - if (resourceFilter != null && resourceFilter.isResourceFiltered((Resource) root)) - return; - } - final IBaseIndexObjectFilter objectFilter = getBaseIndexOptions().getObjectFilterConfiguration(); - if (objectFilter != null && objectFilter.isFiltered(root)) - return; - - // no veto by filters - modelRoots.remove(root); - contentAdapter.removeAdapter(root); - notifyBaseIndexChangeListeners(); - } - - @Override - public void cheapMoveTo(T element, EList targetContainmentReferenceList) { - if (element.eAdapters().contains(contentAdapter) - && targetContainmentReferenceList instanceof NotifyingList) { - final Object listNotifier = ((NotifyingList) targetContainmentReferenceList).getNotifier(); - if (listNotifier instanceof Notifier && ((Notifier) listNotifier).eAdapters().contains(contentAdapter)) { - contentAdapter.ignoreInsertionAndDeletion = element; - try { - targetContainmentReferenceList.add(element); - } finally { - contentAdapter.ignoreInsertionAndDeletion = null; - } - } else { - targetContainmentReferenceList.add(element); - } - } else { - targetContainmentReferenceList.add(element); - } - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void cheapMoveTo(EObject element, EObject parent, EReference containmentFeature) { - metaStore.maintainMetamodel(containmentFeature); - if (containmentFeature.isMany()) - cheapMoveTo(element, (EList) parent.eGet(containmentFeature)); - else if (element.eAdapters().contains(contentAdapter) && parent.eAdapters().contains(contentAdapter)) { - contentAdapter.ignoreInsertionAndDeletion = element; - try { - parent.eSet(containmentFeature, element); - } finally { - contentAdapter.ignoreInsertionAndDeletion = null; - } - } else { - parent.eSet(containmentFeature, element); - } - } - - protected void addRootInternal(Notifier emfRoot) { - if (!((emfRoot instanceof EObject) || (emfRoot instanceof Resource) || (emfRoot instanceof ResourceSet))) { - throw new ViatraBaseException(ViatraBaseException.INVALID_EMFROOT); - } - expandToAdditionalRoot(emfRoot); - } - - @Override - public Set getAllCurrentClasses() { - return instanceStore.getAllCurrentClasses(); - } - - protected boolean isRegistrationNecessary(IndexingLevel level) { - boolean inWildcardMode = isInWildcardMode(level); - if (inWildcardMode && !loggedRegistrationMessage) { - loggedRegistrationMessage = true; - logger.warn("Type registration/unregistration not required in wildcard mode. This message will not be repeated for future occurences."); - } - return !inWildcardMode; - } - - protected void ensureNoListeners(Set unobservedTypes, - final Map>> listenerRegistry) { - if (!Collections.disjoint(unobservedTypes, listenerRegistry.keySet())) - throw new IllegalStateException("Cannot unregister observed types for which there are active listeners"); - } - - protected void ensureNoListenersForDispose() { - if (!(baseIndexChangeListeners.isEmpty() && subscribedFeatureListeners.isEmpty() - && subscribedDataTypeListeners.isEmpty() && subscribedInstanceListeners.isEmpty())) - throw new IllegalStateException("Cannot dispose while there are active listeners"); - } - - /** - * Resamples the values of not well-behaving derived features if those features are also indexed. - */ - @Override - public void resampleDerivedFeatures() { - // otherwise notifications are delivered anyway - if (!baseIndexOptions.isTraverseOnlyWellBehavingDerivedFeatures()) { - // get all required classes - Set allCurrentClasses = instanceStore.getAllCurrentClasses(); - Set featuresToSample = new HashSet<>(); - // collect features to sample - for (EClass cls : allCurrentClasses) { - EList features = cls.getEAllStructuralFeatures(); - for (EStructuralFeature f : features) { - // is feature only sampled? - if (comprehension.onlySamplingFeature(f)) { - featuresToSample.add(f); - } - } - } - - final EMFVisitor removalVisitor = contentAdapter.getVisitorForChange(false); - final EMFVisitor insertionVisitor = contentAdapter.getVisitorForChange(true); - - // iterate on instances - for (final EStructuralFeature f : featuresToSample) { - EClass containingClass = f.getEContainingClass(); - processAllInstances(containingClass, (type, instance) -> - resampleFeatureValueForHolder(instance, f, insertionVisitor, removalVisitor)); - } - notifyBaseIndexChangeListeners(); - } - } - - protected void resampleFeatureValueForHolder(EObject source, EStructuralFeature feature, - EMFVisitor insertionVisitor, EMFVisitor removalVisitor) { - // traverse features and update value - Object newValue = source.eGet(feature); - Set oldValues = instanceStore.getOldValuesForHolderAndFeature(source, toKey(feature)); - if (feature.isMany()) { - resampleManyFeatureValueForHolder(source, feature, newValue, oldValues, insertionVisitor, removalVisitor); - } else { - resampleSingleFeatureValueForHolder(source, feature, newValue, oldValues, insertionVisitor, removalVisitor); - } - - } - - protected void resampleManyFeatureValueForHolder(EObject source, EStructuralFeature feature, Object newValue, - Set oldValues, EMFVisitor insertionVisitor, EMFVisitor removalVisitor) { - InternalEObject internalEObject = (InternalEObject) source; - Collection newValues = (Collection) newValue; - // add those that are in new but not in old - Set newValueSet = new HashSet(newValues); - newValueSet.removeAll(oldValues); - // remove those that are in old but not in new - oldValues.removeAll(newValues); - if (!oldValues.isEmpty()) { - for (Object ov : oldValues) { - comprehension.traverseFeature(removalVisitor, source, feature, ov, null); - } - ENotificationImpl removeNotification = new ENotificationImpl(internalEObject, Notification.REMOVE_MANY, - feature, oldValues, null); - notifyLightweightObservers(source, feature, removeNotification); - } - if (!newValueSet.isEmpty()) { - for (Object nv : newValueSet) { - comprehension.traverseFeature(insertionVisitor, source, feature, nv, null); - } - ENotificationImpl addNotification = new ENotificationImpl(internalEObject, Notification.ADD_MANY, feature, - null, newValueSet); - notifyLightweightObservers(source, feature, addNotification); - } - } - - protected void resampleSingleFeatureValueForHolder(EObject source, EStructuralFeature feature, Object newValue, - Set oldValues, EMFVisitor insertionVisitor, EMFVisitor removalVisitor) { - InternalEObject internalEObject = (InternalEObject) source; - Object oldValue = oldValues.stream().findFirst().orElse(null); - if (!Objects.equals(oldValue, newValue)) { - // value changed - comprehension.traverseFeature(removalVisitor, source, feature, oldValue, null); - comprehension.traverseFeature(insertionVisitor, source, feature, newValue, null); - ENotificationImpl notification = new ENotificationImpl(internalEObject, Notification.SET, feature, oldValue, - newValue); - notifyLightweightObservers(source, feature, notification); - } - } - - @Override - public int countAllInstances(EClass type) { - int result = 0; - - Object typeKey = toKey(type); - Set subTypes = metaStore.getSubTypeMap().get(typeKey); - if (subTypes != null) { - for (Object subTypeKey : subTypes) { - result += statsStore.countInstances(subTypeKey); - } - } - result += statsStore.countInstances(typeKey); - - return result; - } - - @Override - public int countDataTypeInstances(EDataType dataType) { - return statsStore.countInstances(toKey(dataType)); - } - - @Override - public int countFeatureTargets(EObject seedSource, EStructuralFeature feature) { - return featureData(feature).getDistinctValuesOfHolder(seedSource).size(); - } - - @Override - public int countFeatures(EStructuralFeature feature) { - return statsStore.countFeatures(toKey(feature)); - } - - protected IndexingLevel getIndexingLevel(Object type) { - if (type instanceof EClass) { - return getIndexingLevel((EClass)type); - } else if (type instanceof EDataType) { - return getIndexingLevel((EDataType)type); - } else if (type instanceof EStructuralFeature) { - return getIndexingLevel((EStructuralFeature)type); - } else { - throw new IllegalArgumentException("Unexpected type descriptor " + type.toString()); - } - } - - @Override - public IndexingLevel getIndexingLevel(EClass type) { - Object key = toKey(type); - IndexingLevel level = directlyObservedClasses.get(key); - if (level == null) { - level = delayedClasses.get(key); - } - // Wildcard mode is never null - return wildcardMode.merge(level); - } - - @Override - public IndexingLevel getIndexingLevel(EDataType type) { - Object key = toKey(type); - IndexingLevel level = observedDataTypes.get(key); - if (level == null) { - level = delayedDataTypes.get(key); - } - // Wildcard mode is never null - return wildcardMode.merge(level); - } - - @Override - public IndexingLevel getIndexingLevel(EStructuralFeature feature) { - Object key = toKey(feature); - IndexingLevel level = observedFeatures.get(key); - if (level == null) { - level = delayedFeatures.get(key); - } - // Wildcard mode is never null - return wildcardMode.merge(level); - } - - @Override - public void executeAfterTraversal(final Runnable traversalCallback) throws InvocationTargetException { - coalesceTraversals(() -> traversalCallbacks.add(traversalCallback)); - } - - /** - * Records a non-exception incident such as faulty notifications. - * Depending on the strictness setting {@link BaseIndexOptions#isStrictNotificationMode()} and log levels, - * this may be treated as a fatal error, merely logged, or just ignored. - * - * @param msgProvider message supplier that only invoked if the message actually gets logged. - * - * @since 2.3 - */ - protected void logIncident(Supplier msgProvider) { - if (baseIndexOptions.isStrictNotificationMode()) { - // This will cause e.g. query engine to become tainted - String msg = msgProvider.get(); - notifyFatalListener(msg, new IllegalStateException(msg)); - } else { - if (notificationErrorReported) { - if (logger.isDebugEnabled()) { - String msg = msgProvider.get(); - logger.debug(msg); - } - } else { - notificationErrorReported = true; - String msg = msgProvider.get(); - logger.error(msg); - } - } - } - boolean notificationErrorReported = false; - - -// DESIGNATED CUSTOMIZATION POINTS FOR SUBCLASSES - - /** - * Point of customization, called by constructor - * @since 2.3 - */ - protected NavigationHelperContentAdapter initContentAdapter() { - switch (baseIndexOptions.getIndexerProfilerMode()) { - case START_DISABLED: - return new ProfilingNavigationHelperContentAdapter(this, false); - case START_ENABLED: - return new ProfilingNavigationHelperContentAdapter(this, true); - case OFF: - default: - return new NavigationHelperContentAdapter(this); - } - } - - /** - * Point of customization, called by constructor - * @since 2.3 - */ - protected EMFBaseIndexStatisticsStore initStatStore() { - return new EMFBaseIndexStatisticsStore(this, logger); - } - - /** - * Point of customization, called by constructor - * @since 2.3 - */ - protected EMFBaseIndexInstanceStore initInstanceStore() { - return new EMFBaseIndexInstanceStore(this, logger); - } - - /** - * Point of customization, called by constructor - * @since 2.3 - */ - protected EMFBaseIndexMetaStore initMetaStore() { - return new EMFBaseIndexMetaStore(this); - } - - /** - * Point of customization, called by constructor - * @since 2.3 - */ - protected EMFModelComprehension initModelComprehension() { - return new EMFModelComprehension(baseIndexOptions); - } - - /** - * Point of customization, called at runtime - * @since 2.3 - */ - protected TraversingVisitor initTraversingVisitor(final Map toGatherClasses, - final Map toGatherFeatures, final Map toGatherDataTypes, - final Map oldClasses) { - return new NavigationHelperVisitor.TraversingVisitor(this, - toGatherFeatures, toGatherClasses, oldClasses, toGatherDataTypes); - } - - - - /** - * Point of customization, e.g. override to suppress - * @since 2.3 - */ - protected void logIncidentAdapterRemoval(final Notifier notifier) { - logIncident(() -> String.format("Erroneous removal of unattached notification adapter from notifier %s", notifier)); - } - - /** - * Point of customization, e.g. override to suppress - * @since 2.3 - */ - protected void logIncidentFeatureTupleInsertion(final Object value, final EObject holder, Object featureKey) { - logIncident(() -> String.format( - "Error: trying to add duplicate value %s to the unique feature %s of host object %s. This indicates some errors in underlying model representation.", - value, featureKey, holder)); - } - - /** - * Point of customization, e.g. override to suppress - * @since 2.3 - */ - protected void logIncidentFeatureTupleRemoval(final Object value, final EObject holder, Object featureKey) { - logIncident(() -> String.format( - "Error: trying to remove duplicate value %s from the unique feature %s of host object %s. This indicates some errors in underlying model representation.", - value, featureKey, holder)); - } - - /** - * Point of customization, e.g. override to suppress - * @since 2.3 - */ - protected void logIncidentInstanceInsertion(final Object keyClass, final EObject value) { - logIncident(() -> String.format("Notification received to index %s as a %s, but it already exists in the index. This indicates some errors in underlying model representation.", value, keyClass)); - } - - /** - * Point of customization, e.g. override to suppress - * @since 2.3 - */ - protected void logIncidentInstanceRemoval(final Object keyClass, final EObject value) { - logIncident(() -> String.format("Notification received to remove %s as a %s, but it is missing from the index. This indicates some errors in underlying model representation.", value, keyClass)); - } - - /** - * Point of customization, e.g. override to suppress - * @since 2.3 - */ - protected void logIncidentStatRemoval(Object key) { - logIncident(() -> String.format("No instances of %s is registered before calling removeInstance method.", key)); - } - - -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperSetting.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperSetting.java deleted file mode 100644 index 56556ea8..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperSetting.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.base.core; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.EStructuralFeature.Setting; - -/** - * EStructuralFeature.Setting implementation for the NavigationHelper. - * - * @author Tamás Szabó - * - */ -public class NavigationHelperSetting implements Setting { - - private EStructuralFeature feature; - private EObject holder; - private Object value; - - public NavigationHelperSetting() { - super(); - } - - public NavigationHelperSetting(EStructuralFeature feature, EObject holder, Object value) { - super(); - this.feature = feature; - this.holder = holder; - this.value = value; - } - - @Override - public EObject getEObject() { - return holder; - } - - @Override - public EStructuralFeature getEStructuralFeature() { - return feature; - } - - @Override - public Object get(boolean resolve) { - return value; - } - - @Override - public void set(Object newValue) { - this.value = newValue; - } - - @Override - public boolean isSet() { - return (value != null); - } - - @Override - public void unset() { - this.value = null; - } - - @Override - public String toString() { - return "feature = " + feature + " holder = " + holder + " value = " + value; - } -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperType.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperType.java deleted file mode 100644 index 2bab4914..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperType.java +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.base.core; - -public enum NavigationHelperType { - REGISTER, ALL -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperVisitor.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperVisitor.java deleted file mode 100644 index b5de8d20..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/NavigationHelperVisitor.java +++ /dev/null @@ -1,441 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.core; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.eclipse.emf.ecore.EAttribute; -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EClassifier; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.util.EcoreUtil; -import tools.refinery.viatra.runtime.base.api.IndexingLevel; -import tools.refinery.viatra.runtime.base.comprehension.EMFModelComprehension; -import tools.refinery.viatra.runtime.base.comprehension.EMFVisitor; - -public abstract class NavigationHelperVisitor extends EMFVisitor { - - /** - * A visitor for processing a single change event. Does not traverse the model. Uses all the observed types. - */ - public static class ChangeVisitor extends NavigationHelperVisitor { - // local copies to save actual state, in case visitor has to be saved for later due unresolvable proxies - private final IndexingLevel wildcardMode; - private final Map allObservedClasses; - private final Map observedDataTypes; - private final Map observedFeatures; - private final Map sampledClasses; - - public ChangeVisitor(NavigationHelperImpl navigationHelper, boolean isInsertion) { - super(navigationHelper, isInsertion, false); - wildcardMode = navigationHelper.getWildcardLevel(); - allObservedClasses = navigationHelper.getAllObservedClassesInternal(); // new HashSet(); - observedDataTypes = navigationHelper.getObservedDataTypesInternal(); // new HashSet(); - observedFeatures = navigationHelper.getObservedFeaturesInternal(); // new HashSet(); - sampledClasses = new HashMap(); - } - - @Override - protected boolean observesClass(Object eClass) { - return wildcardMode.hasInstances() || (IndexingLevel.FULL == allObservedClasses.get(eClass)) || registerSampledClass(eClass); - } - - protected boolean registerSampledClass(Object eClass) { - Boolean classAlreadyChecked = sampledClasses.get(eClass); - if (classAlreadyChecked != null) { - return classAlreadyChecked; - } - boolean isSampledClass = isSampledClass(eClass); - sampledClasses.put(eClass, isSampledClass); - // do not modify observation configuration during traversal - return false; - } - - @Override - protected boolean observesDataType(Object type) { - return wildcardMode.hasInstances() || (IndexingLevel.FULL == observedDataTypes.get(type)); - } - - @Override - protected boolean observesFeature(Object feature) { - return wildcardMode.hasInstances() || (IndexingLevel.FULL == observedFeatures.get(feature)); - } - - @Override - protected boolean countsFeature(Object feature) { - return wildcardMode.hasStatistics() || observedFeatures.containsKey(feature) && observedFeatures.get(feature).hasStatistics(); - } - - @Override - protected boolean countsDataType(Object type) { - return wildcardMode.hasStatistics() || observedDataTypes.containsKey(type) && observedDataTypes.get(type).hasStatistics(); - } - - @Override - protected boolean countsClass(Object eClass) { - return wildcardMode.hasStatistics() || allObservedClasses.containsKey(eClass) && allObservedClasses.get(eClass).hasStatistics(); - } - } - - /** - * A visitor for a single-pass traversal of the whole model, processing only the given types and inserting them. - */ - public static class TraversingVisitor extends NavigationHelperVisitor { - private final IndexingLevel wildcardMode; - Map features; - Map newClasses; - Map oldClasses; // if decends from an old class, no need to add! - Map classObservationMap; // true for a class even if only a supertype is included in classes; - Map dataTypes; - - public TraversingVisitor(NavigationHelperImpl navigationHelper, Map features, Map newClasses, - Map oldClasses, Map dataTypes) { - super(navigationHelper, true, true); - wildcardMode = navigationHelper.getWildcardLevel(); - this.features = features; - this.newClasses = newClasses; - this.oldClasses = oldClasses; - this.classObservationMap = new HashMap(); - this.dataTypes = dataTypes; - } - - protected IndexingLevel getExistingIndexingLevel(Object eClass){ - IndexingLevel result = IndexingLevel.NONE; - result = result.merge(oldClasses.get(eClass)); - result = result.merge(oldClasses.get(metaStore.getEObjectClassKey())); - if (IndexingLevel.FULL == result) return result; - Set superTypes = metaStore.getSuperTypeMap().get(eClass); - if (superTypes != null){ - for(Object superType: superTypes){ - result = result.merge(oldClasses.get(superType)); - if (IndexingLevel.FULL == result) return result; - } - } - return result; - } - - protected IndexingLevel getRequestedIndexingLevel(Object eClass){ - IndexingLevel result = IndexingLevel.NONE; - result = result.merge(newClasses.get(eClass)); - result = result.merge(newClasses.get(metaStore.getEObjectClassKey())); - if (IndexingLevel.FULL == result) return result; - Set superTypes = metaStore.getSuperTypeMap().get(eClass); - if (superTypes != null){ - for(Object superType: superTypes){ - result = result.merge(newClasses.get(superType)); - if (IndexingLevel.FULL == result) return result; - } - } - return result; - } - - protected IndexingLevel getTraversalIndexing(Object eClass){ - IndexingLevel level = classObservationMap.get(eClass); - if (level == null){ - IndexingLevel existing = getExistingIndexingLevel(eClass); - IndexingLevel requested = getRequestedIndexingLevel(eClass); - - // Calculate the type of indexing which needs to be executed to reach requested indexing state - // Considering indexes which are already available - if (existing == requested || existing == IndexingLevel.FULL) return IndexingLevel.NONE; - if (requested == IndexingLevel.FULL) return IndexingLevel.FULL; - if (requested.hasStatistics() == existing.hasStatistics()) return IndexingLevel.NONE; - if (requested.hasStatistics()) return IndexingLevel.STATISTICS; - return IndexingLevel.NONE; - } - return level; - } - - @Override - protected boolean observesClass(Object eClass) { - if (wildcardMode.hasInstances()) { - return true; - } - return IndexingLevel.FULL == getTraversalIndexing(eClass); - } - - @Override - protected boolean countsClass(Object eClass) { - return wildcardMode.hasStatistics() || getTraversalIndexing(eClass).hasStatistics(); - } - - @Override - protected boolean observesDataType(Object type) { - return wildcardMode.hasInstances() || (IndexingLevel.FULL == dataTypes.get(type)); - } - - @Override - protected boolean observesFeature(Object feature) { - return wildcardMode.hasInstances() || (IndexingLevel.FULL == features.get(feature)); - } - - @Override - protected boolean countsDataType(Object type) { - return wildcardMode.hasStatistics() || dataTypes.containsKey(type) && dataTypes.get(type).hasStatistics(); - } - - @Override - protected boolean countsFeature(Object feature) { - return wildcardMode.hasStatistics() || features.containsKey(feature) && features.get(feature).hasStatistics(); - } - - @Override - public boolean avoidTransientContainmentLink(EObject source, EReference reference, EObject targetObject) { - return !targetObject.eAdapters().contains(navigationHelper.contentAdapter); - } - } - - protected NavigationHelperImpl navigationHelper; - boolean isInsertion; - boolean descendHierarchy; - boolean traverseOnlyWellBehavingDerivedFeatures; - EMFBaseIndexInstanceStore instanceStore; - EMFBaseIndexStatisticsStore statsStore; - EMFBaseIndexMetaStore metaStore; - - NavigationHelperVisitor(NavigationHelperImpl navigationHelper, boolean isInsertion, boolean descendHierarchy) { - super(isInsertion /* preOrder iff insertion */); - this.navigationHelper = navigationHelper; - instanceStore = navigationHelper.instanceStore; - metaStore = navigationHelper.metaStore; - statsStore = navigationHelper.statsStore; - this.isInsertion = isInsertion; - this.descendHierarchy = descendHierarchy; - this.traverseOnlyWellBehavingDerivedFeatures = navigationHelper.getBaseIndexOptions() - .isTraverseOnlyWellBehavingDerivedFeatures(); - } - - @Override - public boolean pruneSubtrees(EObject source) { - return !descendHierarchy; - } - - @Override - public boolean pruneSubtrees(Resource source) { - return !descendHierarchy; - } - - @Override - public boolean pruneFeature(EStructuralFeature feature) { - Object featureKey = toKey(feature); - if (observesFeature(featureKey) || countsFeature(featureKey)) { - return false; - } - if (feature instanceof EAttribute){ - Object dataTypeKey = toKey(((EAttribute) feature).getEAttributeType()); - if (observesDataType(dataTypeKey) || countsDataType(dataTypeKey)) { - return false; - } - } - return !(isInsertion && navigationHelper.isExpansionAllowed() && feature instanceof EReference - && !((EReference) feature).isContainment()); - } - - /** - * @param feature - * key of feature (EStructuralFeature or String id) - */ - protected abstract boolean observesFeature(Object feature); - - /** - * @param feature - * key of data type (EDatatype or String id) - */ - protected abstract boolean observesDataType(Object type); - - /** - * @param feature - * key of class (EClass or String id) - */ - protected abstract boolean observesClass(Object eClass); - - protected abstract boolean countsFeature(Object feature); - - protected abstract boolean countsDataType(Object type); - - protected abstract boolean countsClass(Object eClass); - - @Override - public void visitElement(EObject source) { - EClass eClass = source.eClass(); - if (eClass.eIsProxy()) { - eClass = (EClass) EcoreUtil.resolve(eClass, source); - } - - final Object classKey = toKey(eClass); - if (observesClass(classKey)) { - if (isInsertion) { - instanceStore.insertIntoInstanceSet(classKey, source); - } else { - instanceStore.removeFromInstanceSet(classKey, source); - } - } - if (countsClass(classKey)){ - if (isInsertion){ - statsStore.addInstance(classKey); - } else { - statsStore.removeInstance(classKey); - } - } - } - - @Override - public void visitAttribute(EObject source, EAttribute feature, Object target) { - Object featureKey = toKey(feature); - final Object eAttributeType = toKey(feature.getEAttributeType()); - Object internalValueRepresentation = null; - if (observesFeature(featureKey)) { - // if (internalValueRepresentation == null) // always true - internalValueRepresentation = metaStore.toInternalValueRepresentation(target); - boolean unique = feature.isUnique(); - if (isInsertion) { - instanceStore.insertFeatureTuple(featureKey, unique, internalValueRepresentation, source); - } else { - instanceStore.removeFeatureTuple(featureKey, unique, internalValueRepresentation, source); - } - } - if (countsFeature(featureKey)){ - if (isInsertion) { - statsStore.addFeature(source, featureKey); - }else{ - statsStore.removeFeature(source, featureKey); - } - } - if (observesDataType(eAttributeType)) { - if (internalValueRepresentation == null) - internalValueRepresentation = metaStore.toInternalValueRepresentation(target); - if (isInsertion) { - instanceStore.insertIntoDataTypeMap(eAttributeType, internalValueRepresentation); - } else { - instanceStore.removeFromDataTypeMap(eAttributeType, internalValueRepresentation); - } - } - if (countsDataType(eAttributeType)){ - if (isInsertion){ - statsStore.addInstance(eAttributeType); - } else { - statsStore.removeInstance(eAttributeType); - } - } - } - - @Override - public void visitInternalContainment(EObject source, EReference feature, EObject target) { - visitReference(source, feature, target); - } - - @Override - public void visitNonContainmentReference(EObject source, EReference feature, EObject target) { - visitReference(source, feature, target); - if (isInsertion) { - navigationHelper.considerForExpansion(target); - } - } - - protected void visitReference(EObject source, EReference feature, EObject target) { - Object featureKey = toKey(feature); - if (observesFeature(featureKey)) { - boolean unique = feature.isUnique(); - if (isInsertion) { - instanceStore.insertFeatureTuple(featureKey, unique, target, source); - } else { - instanceStore.removeFeatureTuple(featureKey, unique, target, source); - } - } - if (countsFeature(featureKey)){ - if (isInsertion){ - statsStore.addFeature(source, featureKey); - } else { - statsStore.removeFeature(source, featureKey); - } - } - } - - @Override - // do not attempt to resolve proxies referenced from resources that are still being loaded - public boolean attemptProxyResolutions(EObject source, EReference feature) { - // emptyness is checked first to avoid costly resource lookup in most cases - if (navigationHelper.resolutionDelayingResources.isEmpty()) - return true; - else - return ! navigationHelper.resolutionDelayingResources.contains(source.eResource()); - } - - @Override - public void visitProxyReference(EObject source, EReference reference, EObject targetObject, Integer position) { - if (isInsertion) { // only attempt to resolve proxies if they are inserted - // final Object result = source.eGet(reference, true); - // if (reference.isMany()) { - // // no idea which element to get, have to iterate through - // for (EObject touch : (Iterable) result); - // } - if (navigationHelper.isFeatureResolveIgnored(reference)) - return; // skip resolution; would be ignored anyways - if (position != null && reference.isMany() && attemptProxyResolutions(source, reference)) { - // there is added value in doing the resolution now, when we know the position - // this may save an iteration through the EList if successful - @SuppressWarnings("unchecked") - EObject touch = ((java.util.List) source.eGet(reference, true)).get(position); - // if resolution successful, no further action needed - if (!touch.eIsProxy()) - return; - } - // otherwise, attempt resolution later, at the end of the coalesced traversal block - navigationHelper.delayedProxyResolutions.addPairOrNop(source, reference); - } - } - - protected Object toKey(EStructuralFeature feature) { - return metaStore.toKey(feature); - } - - protected Object toKey(EClassifier eClassifier) { - return metaStore.toKey(eClassifier); - } - - /** - * Decides whether the type must be observed in order to allow re-sampling of any of its features. If not - * well-behaving features are traversed and there is such a feature for this class, the class will be registered - * into the navigation helper, which may cause a re-traversal. - * - */ - protected boolean isSampledClass(Object eClass) { - if (!traverseOnlyWellBehavingDerivedFeatures) { - // TODO we could save this reverse lookup if the calling method would have the EClass, not just the key - EClass knownClass = (EClass) metaStore.getKnownClassifierForKey(eClass); - // check features that are traversed, and whether there is any that must be sampled - for (EStructuralFeature feature : knownClass.getEAllStructuralFeatures()) { - EMFModelComprehension comprehension = navigationHelper.getComprehension(); - if (comprehension.untraversableDirectly(feature)) - continue; - final boolean visitorPrunes = pruneFeature(feature); - if (visitorPrunes) - continue; - // we found a feature to be visited - if (comprehension.onlySamplingFeature(feature)) { - // we found a feature that must be sampled - navigationHelper.registerEClasses(Collections.singleton(feature.getEContainingClass()), IndexingLevel.FULL); - return true; - } - } - } - return false; - } - - @Override - public boolean descendAlongCrossResourceContainments() { - return this.navigationHelper.traversalDescendsAlongCrossResourceContainment(); - } -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/TransitiveClosureHelperImpl.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/TransitiveClosureHelperImpl.java deleted file mode 100644 index 552696cb..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/TransitiveClosureHelperImpl.java +++ /dev/null @@ -1,153 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.base.core; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.util.EContentAdapter; -import tools.refinery.viatra.runtime.base.api.FeatureListener; -import tools.refinery.viatra.runtime.base.api.IndexingLevel; -import tools.refinery.viatra.runtime.base.api.InstanceListener; -import tools.refinery.viatra.runtime.base.api.NavigationHelper; -import tools.refinery.viatra.runtime.base.api.TransitiveClosureHelper; -import tools.refinery.viatra.runtime.base.itc.alg.incscc.IncSCCAlg; -import tools.refinery.viatra.runtime.base.itc.alg.misc.IGraphPathFinder; -import tools.refinery.viatra.runtime.base.itc.igraph.ITcObserver; - -/** - * Implementation class for the {@link TransitiveClosureHelper}. - * It uses a {@link NavigationHelper} instance to wrap an EMF model - * and make it suitable for the {@link IncSCCAlg} algorithm. - * - * @author Tamas Szabo - * - */ -public class TransitiveClosureHelperImpl extends EContentAdapter implements TransitiveClosureHelper, - ITcObserver, FeatureListener, InstanceListener { - - private IncSCCAlg sccAlg; - private Set features; - private Set classes; - private EMFDataSource dataSource; - private List> tcObservers; - private NavigationHelper navigationHelper; - private boolean disposeBaseIndexWhenDisposed; - - public TransitiveClosureHelperImpl(final NavigationHelper navigationHelper, boolean disposeBaseIndexWhenDisposed, Set references) { - this.tcObservers = new ArrayList>(); - this.navigationHelper = navigationHelper; - this.disposeBaseIndexWhenDisposed = disposeBaseIndexWhenDisposed; - - //NavigationHelper only accepts Set upon registration - this.features = new HashSet(references); - this.classes = collectEClasses(); - /*this.classes = Collections.emptySet();*/ - if (!navigationHelper.isInWildcardMode()) - navigationHelper.registerObservedTypes(classes, null, features, IndexingLevel.FULL); - - this.navigationHelper.addFeatureListener(features, this); - this.navigationHelper.addInstanceListener(classes, this); - - this.dataSource = new EMFDataSource(navigationHelper, references, classes); - - this.sccAlg = new IncSCCAlg(dataSource); - this.sccAlg.attachObserver(this); - } - - private Set collectEClasses() { - Set classes = new HashSet(); - for (EStructuralFeature ref : features) { - classes.add(ref.getEContainingClass()); - classes.add(((EReference) ref).getEReferenceType()); - } - return classes; - } - - @Override - public void attachObserver(ITcObserver to) { - this.tcObservers.add(to); - } - - @Override - public void detachObserver(ITcObserver to) { - this.tcObservers.remove(to); - } - - @Override - public Set getAllReachableTargets(EObject source) { - return this.sccAlg.getAllReachableTargets(source); - } - - @Override - public Set getAllReachableSources(EObject target) { - return this.sccAlg.getAllReachableSources(target); - } - - @Override - public boolean isReachable(EObject source, EObject target) { - return this.sccAlg.isReachable(source, target); - } - - @Override - public void tupleInserted(EObject source, EObject target) { - for (ITcObserver to : tcObservers) { - to.tupleInserted(source, target); - } - } - - @Override - public void tupleDeleted(EObject source, EObject target) { - for (ITcObserver to : tcObservers) { - to.tupleDeleted(source, target); - } - } - - @Override - public void dispose() { - this.sccAlg.dispose(); - this.navigationHelper.removeInstanceListener(classes, this); - this.navigationHelper.removeFeatureListener(features, this); - - if (disposeBaseIndexWhenDisposed) - this.navigationHelper.dispose(); - } - - @Override - public void featureInserted(EObject host, EStructuralFeature feature, Object value) { - this.dataSource.notifyEdgeInserted(host, (EObject) value); - } - - @Override - public void featureDeleted(EObject host, EStructuralFeature feature, Object value) { - this.dataSource.notifyEdgeDeleted(host, (EObject) value); - } - - @Override - public void instanceInserted(EClass clazz, EObject instance) { - this.dataSource.notifyNodeInserted(instance); - } - - @Override - public void instanceDeleted(EClass clazz, EObject instance) { - this.dataSource.notifyNodeDeleted(instance); - } - - @Override - public IGraphPathFinder getPathFinder() { - return this.sccAlg.getPathFinder(); - } -} diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/profiler/ProfilingNavigationHelperContentAdapter.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/profiler/ProfilingNavigationHelperContentAdapter.java deleted file mode 100644 index 3ab15430..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/core/profiler/ProfilingNavigationHelperContentAdapter.java +++ /dev/null @@ -1,155 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2019, Laszlo Gati, Zoltan Ujhelyi, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.base.core.profiler; - -import org.eclipse.emf.common.notify.Notification; -import org.eclipse.emf.common.notify.Notifier; -import tools.refinery.viatra.runtime.base.core.NavigationHelperContentAdapter; -import tools.refinery.viatra.runtime.base.core.NavigationHelperImpl; - -/** - * - * @noinstantiate This class is not intended to be instantiated by clients. - * @noreference This class is not intended to be referenced by clients. - */ -public final class ProfilingNavigationHelperContentAdapter extends NavigationHelperContentAdapter { - - private static class StopWatch { - - private long currentStartTimeNs = 0l; - private long totalElapsedTimeNs = 0l; - private boolean running = false; - - /** - * Puts the timer in running state and saves the current time. - */ - private void start() { - currentStartTimeNs = System.nanoTime(); - running = true; - - } - - /** - * Puts the the timer in stopped state and saves the total time spent in started - * state between the last reset and now - */ - private void stop() { - totalElapsedTimeNs = getTotalElapsedTimeNs(); - running = false; - } - - /** - * @return time between the last start and now - */ - private long getCurrentElapsedTimeNs() { - return System.nanoTime() - currentStartTimeNs; - } - - /** - * @return the total time spent in started state between the last reset and now - */ - private long getTotalElapsedTimeNs() { - return running ? getCurrentElapsedTimeNs() + totalElapsedTimeNs : totalElapsedTimeNs; - } - - /** - * Saves the current time and resets all the time spent between the last reset and now. - */ - private void resetTime() { - currentStartTimeNs = System.currentTimeMillis(); - totalElapsedTimeNs = 0; - } - } - - long notificationCount = 0l; - StopWatch watch = new StopWatch(); - boolean isEnabled = false; - - boolean measurement = false; - - public ProfilingNavigationHelperContentAdapter(NavigationHelperImpl navigationHelper, boolean enabled) { - super(navigationHelper); - this.isEnabled = enabled; - } - - @Override - public void notifyChanged(Notification notification) { - // Handle possibility of reentrancy - if (isEnabled && !measurement) { - try { - measurement = true; - notificationCount++; - watch.start(); - super.notifyChanged(notification); - } finally { - watch.stop(); - measurement = false; - } - } else { - super.notifyChanged(notification); - } - } - - @Override - public void setTarget(Notifier target) { - // Handle possibility of reentrancy - if (isEnabled && !measurement) { - try { - measurement = true; - notificationCount++; - watch.start(); - super.setTarget(target); - } finally { - watch.stop(); - measurement = false; - } - } else { - super.setTarget(target); - } - } - - @Override - public void unsetTarget(Notifier target) { - // Handle possibility of reentrancy - if (isEnabled && !measurement) { - try { - measurement = true; - notificationCount++; - watch.start(); - super.unsetTarget(target); - } finally { - watch.stop(); - measurement = false; - } - } else { - super.unsetTarget(target); - } - } - - public long getNotificationCount() { - return notificationCount; - } - - public long getTotalMeasuredTimeInMS() { - return watch.getTotalElapsedTimeNs() / 1_000_000l; - } - - public boolean isEnabled() { - return isEnabled; - } - - public void setEnabled(boolean isEnabled) { - this.isEnabled = isEnabled; - } - - public void resetMeasurement() { - notificationCount = 0; - watch.resetTime(); - } -} \ No newline at end of file diff --git a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/exception/ViatraBaseException.java b/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/exception/ViatraBaseException.java deleted file mode 100644 index fe656c34..00000000 --- a/subprojects/viatra-runtime-base/src/main/java/tools/refinery/viatra/runtime/base/exception/ViatraBaseException.java +++ /dev/null @@ -1,25 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.base.exception; - -import tools.refinery.viatra.runtime.matchers.ViatraQueryRuntimeException; - -public class ViatraBaseException extends ViatraQueryRuntimeException { - - private static final long serialVersionUID = -5145445047912938251L; - - public static final String EMPTY_REF_LIST = "At least one EReference must be provided!"; - public static final String INVALID_EMFROOT = "Emf navigation helper can only be attached on the contents of an EMF EObject, Resource, or ResourceSet."; - - public ViatraBaseException(String s) { - super(s); - } - -} diff --git a/subprojects/viatra-runtime-localsearch/build.gradle.kts b/subprojects/viatra-runtime-localsearch/build.gradle.kts index 2d3886a5..31c0c634 100644 --- a/subprojects/viatra-runtime-localsearch/build.gradle.kts +++ b/subprojects/viatra-runtime-localsearch/build.gradle.kts @@ -10,6 +10,5 @@ plugins { dependencies { implementation(project(":refinery-viatra-runtime")) - implementation(libs.ecore) implementation(libs.slf4j.log4j) } diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/ExecutionLoggerAdapter.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/ExecutionLoggerAdapter.java index 0f7c7b01..bfb76d9a 100644 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/ExecutionLoggerAdapter.java +++ b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/ExecutionLoggerAdapter.java @@ -3,41 +3,40 @@ * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-v20.html. - * + * * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ package tools.refinery.viatra.runtime.localsearch; -import java.util.Optional; -import java.util.function.Consumer; - import tools.refinery.viatra.runtime.localsearch.matcher.ILocalSearchAdapter; import tools.refinery.viatra.runtime.localsearch.matcher.LocalSearchMatcher; import tools.refinery.viatra.runtime.localsearch.operations.IPatternMatcherOperation; import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; -import tools.refinery.viatra.runtime.localsearch.operations.check.nobase.ScopeCheck; import tools.refinery.viatra.runtime.localsearch.plan.SearchPlan; +import java.util.Optional; +import java.util.function.Consumer; + /** * @since 2.0 */ public final class ExecutionLoggerAdapter implements ILocalSearchAdapter { - + volatile String indentation = ""; private final Consumer outputConsumer; - + public ExecutionLoggerAdapter(Consumer outputConsumer) { this.outputConsumer = outputConsumer; } - + private void logMessage(String message) { outputConsumer.accept(message); } - + private void logMessage(String message, Object...args) { outputConsumer.accept(String.format(message, args)); } - + @Override public void patternMatchingStarted(LocalSearchMatcher lsMatcher) { logMessage(indentation + "[ START] " + lsMatcher.getQuerySpecification().getFullyQualifiedName()); @@ -56,7 +55,7 @@ public final class ExecutionLoggerAdapter implements ILocalSearchAdapter { @Override public void operationSelected(SearchPlan plan, ISearchOperation operation, MatchingFrame frame, boolean isBacktrack) { - String category = isBacktrack ? "[ BACK] " : "[SELECT] "; + String category = isBacktrack ? "[ BACK] " : "[SELECT] "; logMessage(indentation + category + operation.toString()); if (operation instanceof IPatternMatcherOperation) { indentation = indentation + "\t"; @@ -66,7 +65,6 @@ public final class ExecutionLoggerAdapter implements ILocalSearchAdapter { @Override public void operationExecuted(SearchPlan plan, ISearchOperation operation, MatchingFrame frame, boolean isSuccessful) { - if (operation instanceof ScopeCheck) return; if (operation instanceof IPatternMatcherOperation && indentation.length() > 0) { indentation = indentation.substring(1); } @@ -77,9 +75,9 @@ public final class ExecutionLoggerAdapter implements ILocalSearchAdapter { public void matchFound(SearchPlan plan, MatchingFrame frame) { logMessage(indentation + "[ MATCH] " + plan.getSourceBody().getPattern().getFullyQualifiedName() + " " + frame.toString()); } - + @Override public void duplicateMatchFound(MatchingFrame frame) { logMessage(indentation + "[ DUPL.] " + frame.toString()); } -} \ No newline at end of file +} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/MatchingFrame.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/MatchingFrame.java index 9caf32bb..bdbc663c 100644 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/MatchingFrame.java +++ b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/MatchingFrame.java @@ -3,21 +3,19 @@ * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-v20.html. - * + * * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ package tools.refinery.viatra.runtime.localsearch; -import java.util.Arrays; -import java.util.stream.Collectors; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EStructuralFeature; import tools.refinery.viatra.runtime.matchers.tuple.IModifiableTuple; import tools.refinery.viatra.runtime.matchers.tuple.VolatileTuple; import tools.refinery.viatra.runtime.matchers.util.Preconditions; +import java.util.Arrays; +import java.util.stream.Collectors; + /** * A MatchingFrame is a Volatile Tuple implementation used by the local search engine internally. */ @@ -34,7 +32,7 @@ public class MatchingFrame extends VolatileTuple implements IModifiableTuple { public MatchingFrame(int frameSize) { this.frame = new Object[frameSize]; } - + /** * Creates a copy of another matching frame; the two frames can be updated separately * @param other @@ -48,7 +46,7 @@ public class MatchingFrame extends VolatileTuple implements IModifiableTuple { /** * Returns the value stored inside the matching frame. - * + * * @param position * @return the element stored in the selected position in the frame, or null if it is not yet set * @throws IndexOutOfBoundsException @@ -60,10 +58,10 @@ public class MatchingFrame extends VolatileTuple implements IModifiableTuple { Preconditions.checkElementIndex(position, frame.length); return frame[position]; } - + /** * Sets the value of the variable at the given position. For internal use in LS matching only. - * + * * @param position the position of the variable within the frame * @param value the value to be set for the variable */ @@ -71,7 +69,7 @@ public class MatchingFrame extends VolatileTuple implements IModifiableTuple { Preconditions.checkElementIndex(position, frame.length); frame[position] = value; } - + public boolean testAndSetValue(Integer position, Object value) { Preconditions.checkElementIndex(position, frame.length); if (frame[position] == null) { @@ -86,20 +84,14 @@ public class MatchingFrame extends VolatileTuple implements IModifiableTuple { public String toString() { return Arrays.stream(frame).map(this::stringRepresentation).collect(Collectors.joining(", ", "[", "]")); } - + private String stringRepresentation(Object obj) { if (obj == null) { return "_"; - } else if (obj instanceof EObject) { - EObject eObject = (EObject) obj; - final EStructuralFeature feature = eObject.eClass().getEStructuralFeature("identifier"); - if (feature != null) { - return String.format("%s : %s", eObject.eGet(feature), eObject.eClass().getName()); - } } return obj.toString(); } - + @Override public int getSize() { return frame.length; @@ -109,7 +101,7 @@ public class MatchingFrame extends VolatileTuple implements IModifiableTuple { public Object get(int index) { return getValue(index); } - + @Override public Object[] getElements() { return Arrays.copyOf(frame, frame.length); diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/ISearchContext.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/ISearchContext.java index 380774bb..71aa4aac 100644 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/ISearchContext.java +++ b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/ISearchContext.java @@ -3,20 +3,12 @@ * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-v20.html. - * + * * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ package tools.refinery.viatra.runtime.localsearch.matcher; -import java.util.Collections; -import java.util.Set; - import org.apache.log4j.Logger; -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EDataType; -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.base.api.IndexingLevel; -import tools.refinery.viatra.runtime.base.api.NavigationHelper; import tools.refinery.viatra.runtime.localsearch.matcher.integration.IAdornmentProvider; import tools.refinery.viatra.runtime.matchers.ViatraQueryRuntimeException; import tools.refinery.viatra.runtime.matchers.backend.IQueryResultProvider; @@ -26,9 +18,11 @@ import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContext; import tools.refinery.viatra.runtime.matchers.util.ICache; import tools.refinery.viatra.runtime.matchers.util.IProvider; +import java.util.Collections; + /** * The {@link ISearchContext} interface allows search operations to reuse platform services such as the indexer. - * + * * @author Zoltan Ujhelyi * @noreference This interface is not intended to be referenced by clients. * @noimplement This interface is not intended to be implemented by clients. @@ -36,43 +30,36 @@ import tools.refinery.viatra.runtime.matchers.util.IProvider; * */ public interface ISearchContext { - + /** * Provides access to the generic query runtime context of the current engine * @since 1.7 */ IQueryRuntimeContext getRuntimeContext(); - - /** - * @param classes - * @param dataTypes - * @param features - */ - void registerObservedTypes(Set classes, Set dataTypes, Set features); - + /** * Returns a matcher for a selected query specification. - * + * * @throws ViatraQueryRuntimeException * @since 1.5 */ IQueryResultProvider getMatcher(CallWithAdornment dependency); - + /** * Allows search operations to cache values through the entire lifecycle of the local search backend. The values are * calculated if not cached before using the given provider, or returned from the cache accordingly. - * + * * @since 1.7 */ T accessBackendLevelCache(Object key, Class clazz, IProvider valueProvider); - + /** * Returns the engine-specific logger - * + * * @since 2.0 */ Logger getLogger(); - + /** * @noreference This class is not intended to be referenced by clients. * @noimplement This interface is not intended to be implemented by clients. @@ -80,34 +67,24 @@ public interface ISearchContext { */ public class SearchContext implements ISearchContext { - private final NavigationHelper navigationHelper; private final IQueryRuntimeContext runtimeContext; - + private final ICache backendLevelCache; private final Logger logger; private final ResultProviderRequestor resultProviderRequestor; - + /** * Initializes a search context using an arbitrary backend context */ - public SearchContext(IQueryBackendContext backendContext, ICache backendLevelCache, + public SearchContext(IQueryBackendContext backendContext, ICache backendLevelCache, ResultProviderRequestor resultProviderRequestor) { this.resultProviderRequestor = resultProviderRequestor; this.runtimeContext = backendContext.getRuntimeContext(); this.logger = backendContext.getLogger(); - this.navigationHelper = null; - + this.backendLevelCache = backendLevelCache; } - public void registerObservedTypes(Set classes, Set dataTypes, Set features) { - if (this.navigationHelper.isInWildcardMode()) { - // In wildcard mode, everything is registered (+ register throws an exception) - return; - } - this.navigationHelper.registerObservedTypes(classes, dataTypes, features, IndexingLevel.FULL); - } - /** * @throws ViatraQueryRuntimeException * @since 2.1 @@ -121,7 +98,7 @@ public interface ISearchContext { } return Collections.emptySet(); }; - return resultProviderRequestor.requestResultProvider(dependency.getCall(), + return resultProviderRequestor.requestResultProvider(dependency.getCall(), IAdornmentProvider.toHint(adornmentProvider)); } @@ -133,11 +110,11 @@ public interface ISearchContext { public IQueryRuntimeContext getRuntimeContext() { return runtimeContext; } - + @Override public Logger getLogger() { return logger; } - + } } diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchBackendFactoryProvider.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchBackendFactoryProvider.java deleted file mode 100644 index bba381d3..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchBackendFactoryProvider.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Zoltan Ujhelyi, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.matcher.integration; - -import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendFactory; -import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendFactoryProvider; - -/** - * @since 2.0 - */ -public class LocalSearchBackendFactoryProvider implements IQueryBackendFactoryProvider { - - @Override - public IQueryBackendFactory getFactory() { - return LocalSearchEMFBackendFactory.INSTANCE; - } - - @Override - public boolean isSystemDefaultSearchBackend() { - return true; - } - -} \ No newline at end of file diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchEMFBackendFactory.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchEMFBackendFactory.java deleted file mode 100644 index 5bffebac..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchEMFBackendFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Marton Bur, Zoltan Ujhelyi, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.matcher.integration; - -import tools.refinery.viatra.runtime.matchers.backend.IMatcherCapability; -import tools.refinery.viatra.runtime.matchers.backend.IQueryBackend; -import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendFactory; -import tools.refinery.viatra.runtime.matchers.backend.QueryEvaluationHint; -import tools.refinery.viatra.runtime.matchers.context.IQueryBackendContext; -import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery; - -/** - * @author Marton Bur, Zoltan Ujhelyi - * @since 2.0 - * - */ -public enum LocalSearchEMFBackendFactory implements IQueryBackendFactory { - - - INSTANCE; - - /** - * @since 1.5 - */ - @Override - public IQueryBackend create(IQueryBackendContext context) { - return new LocalSearchBackend(context) { - - @Override - protected AbstractLocalSearchResultProvider initializeResultProvider(PQuery query, QueryEvaluationHint hints) { - return new LocalSearchResultProvider(this, context, query, planProvider, hints); - } - - @Override - public IQueryBackendFactory getFactory() { - return INSTANCE; - } - }; - } - - @Override - public Class getBackendClass() { - return LocalSearchBackend.class; - } - - /** - * @since 1.4 - */ - @Override - public IMatcherCapability calculateRequiredCapability(PQuery query, QueryEvaluationHint hint) { - return LocalSearchHints.parse(hint); - } - - @Override - public boolean isCaching() { - return false; - } - -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchHints.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchHints.java index 75f338b6..5f3895be 100644 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchHints.java +++ b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchHints.java @@ -3,63 +3,51 @@ * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-v20.html. - * + * * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ package tools.refinery.viatra.runtime.localsearch.matcher.integration; -import static tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchHintOptions.ADORNMENT_PROVIDER; -import static tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchHintOptions.CALL_DELEGATION_STRATEGY; -import static tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchHintOptions.FLATTEN_CALL_PREDICATE; -import static tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchHintOptions.PLANNER_COST_FUNCTION; -import static tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchHintOptions.PLANNER_TABLE_ROW_COUNT; -import static tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchHintOptions.USE_BASE_INDEX; -import static tools.refinery.viatra.runtime.matchers.backend.CommonQueryHintOptions.normalizationTraceCollector; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - import tools.refinery.viatra.runtime.localsearch.planner.cost.ICostFunction; import tools.refinery.viatra.runtime.localsearch.planner.cost.impl.IndexerBasedConstraintCostFunction; import tools.refinery.viatra.runtime.localsearch.planner.cost.impl.StatisticsBasedConstraintCostFunction; -import tools.refinery.viatra.runtime.localsearch.planner.cost.impl.VariableBindingBasedCostFunction; -import tools.refinery.viatra.runtime.matchers.backend.ICallDelegationStrategy; -import tools.refinery.viatra.runtime.matchers.backend.IMatcherCapability; -import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendFactory; -import tools.refinery.viatra.runtime.matchers.backend.QueryEvaluationHint; -import tools.refinery.viatra.runtime.matchers.backend.QueryHintOption; -import tools.refinery.viatra.runtime.matchers.psystem.rewriters.DefaultFlattenCallPredicate; +import tools.refinery.viatra.runtime.matchers.backend.*; import tools.refinery.viatra.runtime.matchers.psystem.rewriters.IFlattenCallPredicate; import tools.refinery.viatra.runtime.matchers.psystem.rewriters.IRewriterTraceCollector; -import tools.refinery.viatra.runtime.matchers.psystem.rewriters.NeverFlattenCallPredicate; import tools.refinery.viatra.runtime.matchers.psystem.rewriters.NopTraceCollector; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import static tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchHintOptions.*; +import static tools.refinery.viatra.runtime.matchers.backend.CommonQueryHintOptions.normalizationTraceCollector; + /** * Type safe builder and extractor for Local search specific hints - * + * * @author Grill Balázs * @since 1.4 * */ public final class LocalSearchHints implements IMatcherCapability { - + private Boolean useBase = null; - + private Integer rowCount = null; - + private ICostFunction costFunction = null; - + private IFlattenCallPredicate flattenCallPredicate = null; - + private ICallDelegationStrategy callDelegationStrategy = null; - + private IAdornmentProvider adornmentProvider = null; - + private IRewriterTraceCollector traceCollector = NopTraceCollector.INSTANCE; - + private IQueryBackendFactory backendFactory = null; - + private LocalSearchHints() {} /** @@ -68,53 +56,14 @@ public final class LocalSearchHints implements IMatcherCapability { public static LocalSearchHints getDefaultOverriddenBy(QueryEvaluationHint overridingHint){ return parse(getDefault().build(overridingHint)); } - + /** * Default settings which are considered the most safe, providing a reasonable performance for most of the cases. Assumes the availability of the base indexer. */ public static LocalSearchHints getDefault(){ - LocalSearchHints result = new LocalSearchHints(); - result.useBase = USE_BASE_INDEX.getDefaultValue(); - result.rowCount = PLANNER_TABLE_ROW_COUNT.getDefaultValue(); - result.costFunction = PLANNER_COST_FUNCTION.getDefaultValue(); - result.flattenCallPredicate = FLATTEN_CALL_PREDICATE.getDefaultValue(); - result.callDelegationStrategy = CALL_DELEGATION_STRATEGY.getDefaultValue(); - result.adornmentProvider = ADORNMENT_PROVIDER.getDefaultValue(); - result.backendFactory = LocalSearchEMFBackendFactory.INSTANCE; - return result; + return getDefaultGeneric(); } - - /** - * With this setting, the patterns are flattened before planning. This may cause performance gain in some cases compared to the {@link #getDefault()} settings, - * However this should be used with care for patterns containing calls with several bodies. - */ - public static LocalSearchHints getDefaultFlatten(){ - LocalSearchHints result = new LocalSearchHints(); - result.useBase = true; - result.rowCount = 4; - result.costFunction = new IndexerBasedConstraintCostFunction(); - result.flattenCallPredicate = new DefaultFlattenCallPredicate(); - result.callDelegationStrategy = CALL_DELEGATION_STRATEGY.getDefaultValue(); - result.adornmentProvider = ADORNMENT_PROVIDER.getDefaultValue(); - result.backendFactory = LocalSearchEMFBackendFactory.INSTANCE; - return result; - } - - /** - * Settings to be used when the base index is not available. - */ - public static LocalSearchHints getDefaultNoBase(){ - LocalSearchHints result = new LocalSearchHints(); - result.useBase = false; - result.rowCount = 4; - result.costFunction = new VariableBindingBasedCostFunction(); - result.flattenCallPredicate = new NeverFlattenCallPredicate(); - result.callDelegationStrategy = ICallDelegationStrategy.FULL_BACKEND_ADHESION; - result.adornmentProvider = ADORNMENT_PROVIDER.getDefaultValue(); - result.backendFactory = LocalSearchEMFBackendFactory.INSTANCE; - return result; - } - + /** * Initializes the generic (not EMF specific) search backend with the default settings * @since 1.7 @@ -130,7 +79,7 @@ public final class LocalSearchHints implements IMatcherCapability { result.backendFactory = LocalSearchGenericBackendFactory.INSTANCE; return result; } - + /** * Initializes the default search backend with hybrid-enabled settings * @since 2.1 @@ -142,7 +91,7 @@ public final class LocalSearchHints implements IMatcherCapability { new DontFlattenIncrementalPredicate(), new DontFlattenDisjunctive()); return result; } - + /** * Initializes the generic (not EMF specific) search backend with hybrid-enabled settings * @since 2.1 @@ -154,10 +103,10 @@ public final class LocalSearchHints implements IMatcherCapability { new DontFlattenIncrementalPredicate(), new DontFlattenDisjunctive()); return result; } - + public static LocalSearchHints parse(QueryEvaluationHint hint){ LocalSearchHints result = new LocalSearchHints(); - + result.useBase = USE_BASE_INDEX.getValueOrNull(hint); result.rowCount = PLANNER_TABLE_ROW_COUNT.getValueOrNull(hint); result.flattenCallPredicate = FLATTEN_CALL_PREDICATE.getValueOrNull(hint); @@ -165,15 +114,15 @@ public final class LocalSearchHints implements IMatcherCapability { result.costFunction = PLANNER_COST_FUNCTION.getValueOrNull(hint); result.adornmentProvider = ADORNMENT_PROVIDER.getValueOrNull(hint); result.traceCollector = normalizationTraceCollector.getValueOrDefault(hint); - + return result; } - + private Map, Object> calculateHintMap() { Map, Object> map = new HashMap<>(); if (useBase != null){ - USE_BASE_INDEX.insertOverridingValue(map, useBase); + USE_BASE_INDEX.insertOverridingValue(map, useBase); } if (rowCount != null){ PLANNER_TABLE_ROW_COUNT.insertOverridingValue(map, rowCount); @@ -195,43 +144,43 @@ public final class LocalSearchHints implements IMatcherCapability { } return map; } - + public QueryEvaluationHint build(){ Map, Object> map = calculateHintMap(); return new QueryEvaluationHint(map, backendFactory); } - + /** * @since 1.7 */ public QueryEvaluationHint build(QueryEvaluationHint overridingHint) { if (overridingHint == null) return build(); - + IQueryBackendFactory factory = (overridingHint.getQueryBackendFactory() == null) ? this.backendFactory : overridingHint.getQueryBackendFactory(); - + Map, Object> hints = calculateHintMap(); if (overridingHint.getBackendHintSettings() != null) { hints.putAll(overridingHint.getBackendHintSettings()); } - + return new QueryEvaluationHint(hints, factory); } - + public boolean isUseBase() { return useBase; } - + public ICostFunction getCostFunction() { return costFunction; } - + public IFlattenCallPredicate getFlattenCallPredicate() { return flattenCallPredicate; } - + /** * @since 2.1 */ @@ -242,7 +191,7 @@ public final class LocalSearchHints implements IMatcherCapability { public Integer getRowCount() { return rowCount; } - + /** * @since 1.5 */ @@ -256,28 +205,28 @@ public final class LocalSearchHints implements IMatcherCapability { public IRewriterTraceCollector getTraceCollector() { return traceCollector == null ? normalizationTraceCollector.getDefaultValue() : traceCollector; } - + public LocalSearchHints setUseBase(boolean useBase) { this.useBase = useBase; return this; } - + public LocalSearchHints setRowCount(int rowCount) { this.rowCount = rowCount; return this; } - + public LocalSearchHints setCostFunction(ICostFunction costFunction) { this.costFunction = costFunction; return this; } - + public LocalSearchHints setFlattenCallPredicate(IFlattenCallPredicate flattenCallPredicate) { this.flattenCallPredicate = flattenCallPredicate; return this; } - - + + /** * @since 2.1 */ @@ -293,7 +242,7 @@ public final class LocalSearchHints implements IMatcherCapability { this.traceCollector = traceCollector; return this; } - + /** * @since 1.5 */ @@ -301,37 +250,37 @@ public final class LocalSearchHints implements IMatcherCapability { this.adornmentProvider = adornmentProvider; return this; } - + public static LocalSearchHints customizeUseBase(boolean useBase){ return new LocalSearchHints().setUseBase(useBase); } - + public static LocalSearchHints customizeRowCount(int rowCount){ return new LocalSearchHints().setRowCount(rowCount); } - + public static LocalSearchHints customizeCostFunction(ICostFunction costFunction){ return new LocalSearchHints().setCostFunction(costFunction); } - + public static LocalSearchHints customizeFlattenCallPredicate(IFlattenCallPredicate predicate){ return new LocalSearchHints().setFlattenCallPredicate(predicate); } - + /** * @since 2.1 */ public static LocalSearchHints customizeCallDelegationStrategy(ICallDelegationStrategy strategy){ return new LocalSearchHints().setCallDelegationStrategy(strategy); } - + /** * @since 1.5 */ public static LocalSearchHints customizeAdornmentProvider(IAdornmentProvider adornmentProvider){ return new LocalSearchHints().setAdornmentProvider(adornmentProvider); } - + /** * @since 1.6 */ diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchResultProvider.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchResultProvider.java deleted file mode 100644 index a3017b18..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/matcher/integration/LocalSearchResultProvider.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Marton Bur, Zoltan Ujhelyi, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.matcher.integration; - -import tools.refinery.viatra.runtime.localsearch.plan.IPlanProvider; -import tools.refinery.viatra.runtime.localsearch.planner.compiler.EMFOperationCompiler; -import tools.refinery.viatra.runtime.localsearch.planner.compiler.IOperationCompiler; -import tools.refinery.viatra.runtime.matchers.ViatraQueryRuntimeException; -import tools.refinery.viatra.runtime.matchers.backend.QueryEvaluationHint; -import tools.refinery.viatra.runtime.matchers.context.IQueryBackendContext; -import tools.refinery.viatra.runtime.matchers.context.IndexingService; -import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery; - -/** - * @author Marton Bur, Zoltan Ujhelyi - * - */ -public class LocalSearchResultProvider extends AbstractLocalSearchResultProvider { - - /** - * @throws ViatraQueryRuntimeException - * @since 1.5 - */ - public LocalSearchResultProvider(LocalSearchBackend backend, IQueryBackendContext context, PQuery query, - IPlanProvider planProvider) { - this(backend, context, query, planProvider, null); - } - - /** - * @throws ViatraQueryRuntimeException - * @since 1.5 - */ - public LocalSearchResultProvider(LocalSearchBackend backend, IQueryBackendContext context, PQuery query, - IPlanProvider planProvider, QueryEvaluationHint userHints) { - super(backend, context, query, planProvider, userHints); - } - - @Override - protected void indexInitializationBeforePlanning() { - super.indexInitializationBeforePlanning(); - - indexReferredTypesOfQuery(query, IndexingService.STATISTICS); - } - - @Override - protected IOperationCompiler getOperationCompiler(IQueryBackendContext backendContext, - LocalSearchHints configuration) { - return new EMFOperationCompiler(runtimeContext, configuration.isUseBase()); - } -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/ContainmentCheck.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/ContainmentCheck.java deleted file mode 100644 index 9dfb16f5..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/ContainmentCheck.java +++ /dev/null @@ -1,85 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Zoltan Ujhelyi, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.check; - -import java.util.Arrays; -import java.util.List; -import java.util.function.Function; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.util.EcoreUtil; -import tools.refinery.viatra.runtime.localsearch.MatchingFrame; -import tools.refinery.viatra.runtime.localsearch.exceptions.LocalSearchException; -import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; -import tools.refinery.viatra.runtime.localsearch.operations.CheckOperationExecutor; -import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; - -/** - * A simple operation that checks whether a {@link EStructuralFeature} connects two selected variables. - * @noextend This class is not intended to be subclassed by clients. - */ -public class ContainmentCheck implements ISearchOperation { - - private class Executor extends CheckOperationExecutor { - - @Override - protected boolean check(MatchingFrame frame, ISearchContext context) { - try { - EObject child = (EObject) frame.getValue(childPosition); - EObject container = (EObject)frame.getValue(containerPosition); - - if (transitive) { - return EcoreUtil.isAncestor(container, child); - } else { - return child.eContainer().equals(container); - } - } catch (ClassCastException e) { - throw new LocalSearchException(LocalSearchException.TYPE_ERROR, e); - } - } - - @Override - public ISearchOperation getOperation() { - return ContainmentCheck.this; - } - } - - int childPosition; - int containerPosition; - private boolean transitive; - - public ContainmentCheck(int childPosition, int containerPosition, boolean transitive) { - super(); - this.childPosition = childPosition; - this.containerPosition = containerPosition; - this.transitive = transitive; - } - - @Override - public ISearchOperationExecutor createExecutor() { - return new Executor(); - } - - @Override - public String toString() { - return toString(Object::toString); - } - - @Override - public String toString(Function variableMapping) { - return "check containment +"+variableMapping.apply(containerPosition)+" <>--> +"+childPosition+(transitive ? " transitively" : " directly"); - } - - @Override - public List getVariablePositions() { - return Arrays.asList(childPosition, containerPosition); - } - -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/InstanceOfClassCheck.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/InstanceOfClassCheck.java deleted file mode 100644 index 68d92040..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/InstanceOfClassCheck.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Zoltan Ujhelyi, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.check; - -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EObject; -import tools.refinery.viatra.runtime.localsearch.MatchingFrame; -import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; -import tools.refinery.viatra.runtime.localsearch.operations.CheckOperationExecutor; -import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; - -/** - * @author Zoltan Ujhelyi - * @noextend This class is not intended to be subclassed by clients. - */ -public class InstanceOfClassCheck implements ISearchOperation { - - private class Executor extends CheckOperationExecutor { - - @Override - protected boolean check(MatchingFrame frame, ISearchContext context) { - Objects.requireNonNull(frame.getValue(position), () -> String.format("Invalid plan, variable %s unbound", position)); - if (frame.getValue(position) instanceof EObject) { - return clazz.isSuperTypeOf(((EObject) frame.getValue(position)).eClass()); - } - return false; - } - - @Override - public ISearchOperation getOperation() { - return InstanceOfClassCheck.this; - } - } - - private int position; - private EClass clazz; - - public InstanceOfClassCheck(int position, EClass clazz) { - this.position = position; - this.clazz = clazz; - - } - - @Override - public ISearchOperationExecutor createExecutor() { - return new Executor(); - } - - @Override - public String toString() { - return toString(Object::toString); - } - - @Override - public String toString(Function variableMapping) { - return "check "+clazz.getName()+"(+"+ variableMapping.apply(position)+")"; - } - - @Override - public List getVariablePositions() { - return Arrays.asList(position); - } - -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/InstanceOfDataTypeCheck.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/InstanceOfDataTypeCheck.java deleted file mode 100644 index 940104a2..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/InstanceOfDataTypeCheck.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Zoltan Ujhelyi, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.check; - -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import org.eclipse.emf.ecore.EDataType; -import tools.refinery.viatra.runtime.localsearch.MatchingFrame; -import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; -import tools.refinery.viatra.runtime.localsearch.operations.CheckOperationExecutor; -import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; - -/** - * @author Zoltan Ujhelyi - * @noextend This class is not intended to be subclassed by clients. - */ -public class InstanceOfDataTypeCheck implements ISearchOperation { - - private class Executor extends CheckOperationExecutor { - - @Override - protected boolean check(MatchingFrame frame, ISearchContext context) { - Objects.requireNonNull(frame.getValue(position), () -> String.format("Invalid plan, variable %s unbound", position)); - return dataType.isInstance(frame.getValue(position)); - } - - @Override - public ISearchOperation getOperation() { - return InstanceOfDataTypeCheck.this; - } - } - - private int position; - private EDataType dataType; - - public InstanceOfDataTypeCheck(int position, EDataType dataType) { - this.position = position; - this.dataType = dataType; - - } - - @Override - public ISearchOperationExecutor createExecutor() { - return new Executor(); - } - - @Override - public String toString() { - return toString(Object::toString); - } - - @Override - public String toString(Function variableMapping) { - return "check "+dataType.getName()+"(+"+variableMapping.apply(position)+")"; - } - - @Override - public List getVariablePositions() { - return Arrays.asList(position); - } - -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/InstanceOfJavaClassCheck.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/InstanceOfJavaClassCheck.java deleted file mode 100644 index 1da312a0..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/InstanceOfJavaClassCheck.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Zoltan Ujhelyi, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.check; - -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import tools.refinery.viatra.runtime.localsearch.MatchingFrame; -import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; -import tools.refinery.viatra.runtime.localsearch.operations.CheckOperationExecutor; -import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; - -/** - * @author Zoltan Ujhelyi - * @since 1.4 - * @noextend This class is not intended to be subclassed by clients. - */ -public class InstanceOfJavaClassCheck implements ISearchOperation { - - private class Executor extends CheckOperationExecutor { - - @Override - protected boolean check(MatchingFrame frame, ISearchContext context) { - Objects.requireNonNull(frame.getValue(position), () -> String.format("Invalid plan, variable %s unbound", position)); - return clazz.isInstance(frame.getValue(position)); - } - - @Override - public ISearchOperation getOperation() { - return InstanceOfJavaClassCheck.this; - } - } - - private int position; - private Class clazz; - - public InstanceOfJavaClassCheck(int position, Class clazz) { - this.position = position; - this.clazz = clazz; - - } - - @Override - public ISearchOperationExecutor createExecutor() { - return new Executor(); - } - - @Override - public String toString() { - return toString(Object::toString); - } - - @Override - public String toString(Function variableMapping) { - return "check java "+clazz.getName()+"(+"+variableMapping.apply(position)+")"; - } - - @Override - public List getVariablePositions() { - return Arrays.asList(position); - } - -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/StructuralFeatureCheck.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/StructuralFeatureCheck.java deleted file mode 100644 index a3e5bc40..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/StructuralFeatureCheck.java +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Zoltan Ujhelyi, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.check; - -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.localsearch.MatchingFrame; -import tools.refinery.viatra.runtime.localsearch.exceptions.LocalSearchException; -import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; -import tools.refinery.viatra.runtime.localsearch.operations.CheckOperationExecutor; -import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; - -/** - * A simple operation that checks whether a {@link EStructuralFeature} connects two selected variables. - * @noextend This class is not intended to be subclassed by clients. - */ -public class StructuralFeatureCheck implements ISearchOperation { - - private class Executor extends CheckOperationExecutor { - - @Override - protected boolean check(MatchingFrame frame, ISearchContext context) { - Objects.requireNonNull(frame.getValue(sourcePosition), () -> String.format("Invalid plan, variable %s unbound", sourcePosition)); - Objects.requireNonNull(frame.getValue(targetPosition), () -> String.format("Invalid plan, variable %s unbound", targetPosition)); - try { - EObject source = (EObject) frame.getValue(sourcePosition); - if(! feature.getEContainingClass().isSuperTypeOf(source.eClass()) ){ - // TODO planner should ensure the proper supertype relation, see bug 500968 - return false; - } - Object target = frame.getValue(targetPosition); - if (feature.isMany()) { - return ((Collection) source.eGet(feature)).contains(target); - } else { - return target.equals(source.eGet(feature)); - } - } catch (ClassCastException e) { - throw new LocalSearchException(LocalSearchException.TYPE_ERROR, e); - } - } - - @Override - public ISearchOperation getOperation() { - return StructuralFeatureCheck.this; - } - } - - int sourcePosition; - int targetPosition; - EStructuralFeature feature; - - public StructuralFeatureCheck(int sourcePosition, int targetPosition, EStructuralFeature feature) { - super(); - this.sourcePosition = sourcePosition; - this.targetPosition = targetPosition; - this.feature = feature; - } - - @Override - public ISearchOperationExecutor createExecutor() { - return new Executor(); - } - - @Override - public String toString() { - return toString(Object::toString); - } - - @Override - public String toString(Function variableMapping) { - return "check "+feature.getContainerClass().getSimpleName()+"."+feature.getName()+"(+"+variableMapping.apply(sourcePosition)+", +"+variableMapping.apply(targetPosition)+")"; - } - - @Override - public List getVariablePositions() { - return Arrays.asList(sourcePosition, targetPosition); - } - -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/nobase/ScopeCheck.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/nobase/ScopeCheck.java deleted file mode 100644 index 06989fdc..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/check/nobase/ScopeCheck.java +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Marton Bur, Zoltan Ujhelyi, Akos Horvath, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.check.nobase; - -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.util.EcoreUtil; -import tools.refinery.viatra.runtime.base.api.filters.IBaseIndexObjectFilter; -import tools.refinery.viatra.runtime.emf.EMFScope; -import tools.refinery.viatra.runtime.localsearch.MatchingFrame; -import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; -import tools.refinery.viatra.runtime.localsearch.operations.CheckOperationExecutor; -import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; - -/** - * This operation simply checks if a model element is part of the Query Scope - * - * @author Marton Bur - * - */ -public class ScopeCheck implements ISearchOperation { - private class Executor extends CheckOperationExecutor { - - @Override - protected boolean check(MatchingFrame frame, ISearchContext context) { - Objects.requireNonNull(frame.getValue(position), () -> String.format("Invalid plan, variable %d unbound", position)); - Object value = frame.getValue(position); - if(value instanceof EObject){ - EObject eObject = (EObject) value; - IBaseIndexObjectFilter filterConfiguration = scope.getOptions().getObjectFilterConfiguration(); - boolean filtered = false; - if(filterConfiguration != null){ - filtered = filterConfiguration.isFiltered(eObject); - } - if(filtered){ - return false; - } else { - return EcoreUtil.isAncestor(scope.getScopeRoots(), eObject); - } - } else { - return true; - } - } - - @Override - public ISearchOperation getOperation() { - return ScopeCheck.this; - } - - } - - private int position; - private EMFScope scope; - - public ScopeCheck(int position, EMFScope scope) { - this.position = position; - this.scope = scope; - - } - - @Override - public ISearchOperationExecutor createExecutor() { - return new Executor(); - } - - @Override - public String toString() { - return toString(Object::toString); - } - - - @Override - public String toString(Function variableMapping) { - return "check +"+variableMapping.apply(position) +" in scope "+scope; - } - - @Override - public List getVariablePositions() { - return Arrays.asList(position); - } -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/ExtendToEStructuralFeatureSource.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/ExtendToEStructuralFeatureSource.java deleted file mode 100644 index 04f0a8de..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/ExtendToEStructuralFeatureSource.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Zoltan Ujhelyi, Akos Horvath, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.extend; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.function.Function; -import java.util.stream.StreamSupport; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.emf.types.EStructuralFeatureInstancesKey; -import tools.refinery.viatra.runtime.localsearch.MatchingFrame; -import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; -import tools.refinery.viatra.runtime.localsearch.operations.IIteratingSearchOperation; -import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContext; -import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; -import tools.refinery.viatra.runtime.matchers.tuple.VolatileMaskedTuple; - -/** - * Iterates over all sources of {@link EStructuralFeature} using an {@link IQueryRuntimeContext VIATRA Base indexer}. - * It is assumed that the indexer is initialized for the selected {@link EStructuralFeature}. - * - */ -public class ExtendToEStructuralFeatureSource implements IIteratingSearchOperation { - - private class Executor extends SingleValueExtendOperationExecutor { - - private VolatileMaskedTuple maskedTuple; - - public Executor(int position) { - super(position); - this.maskedTuple = new VolatileMaskedTuple(mask); - } - - - @Override - public Iterator getIterator(MatchingFrame frame, ISearchContext context) { - maskedTuple.updateTuple(frame); - Iterable values = context.getRuntimeContext().enumerateValues(type, indexerMask, maskedTuple); - return StreamSupport.stream(values.spliterator(), false) - .filter(EObject.class::isInstance) - .map(EObject.class::cast) - .iterator(); - } - - @Override - public ISearchOperation getOperation() { - return ExtendToEStructuralFeatureSource.this; - } - } - - private final int sourcePosition; - private final int targetPosition; - private final EStructuralFeature feature; - private final IInputKey type; - private static final TupleMask indexerMask = TupleMask.fromSelectedIndices(2, new int[] {1}); - private final TupleMask mask; - - /** - * @since 1.7 - */ - public ExtendToEStructuralFeatureSource(int sourcePosition, int targetPosition, EStructuralFeature feature, TupleMask mask) { - this.sourcePosition = sourcePosition; - this.targetPosition = targetPosition; - this.feature = feature; - this.mask = mask; - this.type = new EStructuralFeatureInstancesKey(feature); - } - - public EStructuralFeature getFeature() { - return feature; - } - - @Override - public ISearchOperationExecutor createExecutor() { - return new Executor(sourcePosition); - } - - @Override - public String toString() { - return toString(Object::toString); - } - - @Override - public String toString(Function variableMapping) { - return "extend "+feature.getContainerClass().getSimpleName()+"."+feature.getName()+"(-"+variableMapping.apply(sourcePosition)+", +"+variableMapping.apply(targetPosition)+") indexed"; - } - - @Override - public List getVariablePositions() { - return Arrays.asList(sourcePosition, targetPosition); - } - - /** - * @since 1.4 - */ - @Override - public IInputKey getIteratedInputKey() { - return type; - } - -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/ExtendToEStructuralFeatureTarget.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/ExtendToEStructuralFeatureTarget.java deleted file mode 100644 index 4304fc8d..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/ExtendToEStructuralFeatureTarget.java +++ /dev/null @@ -1,102 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Zoltan Ujhelyi, Akos Horvath, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.extend; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.function.Function; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.localsearch.MatchingFrame; -import tools.refinery.viatra.runtime.localsearch.exceptions.LocalSearchException; -import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; -import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; - -/** - * Iterates over all sources of {@link EStructuralFeature} - */ -public class ExtendToEStructuralFeatureTarget implements ISearchOperation { - - private class Executor extends SingleValueExtendOperationExecutor { - - public Executor(int position) { - super(position); - } - - @SuppressWarnings("unchecked") - @Override - public Iterator getIterator(MatchingFrame frame, ISearchContext context) { - try { - final EObject value = (EObject) frame.getValue(sourcePosition); - if(! feature.getEContainingClass().isSuperTypeOf(value.eClass()) ){ - // TODO planner should ensure the proper supertype relation - return Collections.emptyIterator(); - } - final Object featureValue = value.eGet(feature); - if (feature.isMany()) { - if (featureValue != null) { - final Collection objectCollection = (Collection) featureValue; - return objectCollection.iterator(); - } else { - return Collections.emptyIterator(); - } - } else { - if (featureValue != null) { - return Collections.singletonList(featureValue).iterator(); - } else { - return Collections.emptyIterator(); - } - } - } catch (ClassCastException e) { - throw new LocalSearchException("Invalid feature source in parameter" + Integer.toString(sourcePosition), e); - } - } - - @Override - public ISearchOperation getOperation() { - return ExtendToEStructuralFeatureTarget.this; - } - } - - private final int sourcePosition; - private final int targetPosition; - private final EStructuralFeature feature; - - public ExtendToEStructuralFeatureTarget(int sourcePosition, int targetPosition, EStructuralFeature feature) { - this.sourcePosition = sourcePosition; - this.targetPosition = targetPosition; - this.feature = feature; - } - - @Override - public String toString() { - return toString(Object::toString); - } - - @Override - public String toString(Function variableMapping) { - return "extend "+feature.getEContainingClass().getName()+"."+feature.getName()+"(+"+variableMapping.apply(sourcePosition)+", -"+ variableMapping.apply(targetPosition) +")"; - } - - @Override - public ISearchOperationExecutor createExecutor() { - return new Executor(targetPosition); - } - - - @Override - public List getVariablePositions() { - return Arrays.asList(sourcePosition, targetPosition); - } - -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverChildren.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverChildren.java deleted file mode 100644 index 10764aea..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverChildren.java +++ /dev/null @@ -1,90 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Zoltan Ujhelyi, Akos Horvath, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.extend; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.function.Function; - -import org.eclipse.emf.ecore.EObject; -import tools.refinery.viatra.runtime.localsearch.MatchingFrame; -import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; -import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; -import tools.refinery.viatra.runtime.matchers.util.Preconditions; - -/** - * Iterates all child elements of a selected EObjects. - * - * @author Zoltan Ujhelyi - * - */ -public class IterateOverChildren implements ISearchOperation { - - private class Executor extends SingleValueExtendOperationExecutor { - - public Executor(int position) { - super(position); - } - - @Override - public Iterator getIterator(MatchingFrame frame, ISearchContext context) { - Preconditions.checkState(frame.get(sourcePosition) instanceof EObject, "Only children of EObject elements are supported."); - EObject source = (EObject) frame.get(sourcePosition); - if(transitive) { - return source.eAllContents(); - } else { - return source.eContents().iterator(); - } - } - - @Override - public ISearchOperation getOperation() { - return IterateOverChildren.this; - } - } - - private final int position; - private int sourcePosition; - private final boolean transitive; - - /** - * - * @param position the position of the variable storing the child elements - * @param sourcePosition the position of the variable storing the parent root; must be bound - * @param transitive if true, child elements are iterated over transitively - */ - public IterateOverChildren(int position, int sourcePosition, boolean transitive) { - this.position = position; - this.sourcePosition = sourcePosition; - this.transitive = transitive; - } - - @Override - public String toString() { - return toString(Object::toString); - } - - @Override - public String toString(Function variableMapping) { - return "extend containment +"+variableMapping.apply(sourcePosition)+" <>--> -"+variableMapping.apply(position)+(transitive ? " transitively" : " directly"); - } - - @Override - public ISearchOperationExecutor createExecutor() { - return new Executor(position); - } - - - @Override - public List getVariablePositions() { - return Arrays.asList(position, sourcePosition); - } - -} \ No newline at end of file diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverContainers.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverContainers.java deleted file mode 100644 index df7e18c9..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverContainers.java +++ /dev/null @@ -1,126 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Zoltan Ujhelyi, Akos Horvath, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.extend; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.function.Function; - -import org.eclipse.emf.ecore.EObject; -import tools.refinery.viatra.runtime.localsearch.MatchingFrame; -import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; -import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; -import tools.refinery.viatra.runtime.matchers.util.Preconditions; - -/** - * Iterates all child elements of a selected EObjects. - * - * @author Zoltan Ujhelyi - * - */ -public class IterateOverContainers implements ISearchOperation { - - /** - * A helper iterator for transitively traversing a parent of an object - */ - private static final class ParentIterator implements Iterator { - private EObject current; - - public ParentIterator(EObject source) { - this.current = source; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public EObject next() { - EObject newObject = current.eContainer(); - if (newObject == null) { - throw new NoSuchElementException(String.format("No more parents available for EObject %s", current)); - } - current = newObject; - return current; - } - - @Override - public boolean hasNext() { - return current.eContainer() != null; - } - } - - private class Executor extends SingleValueExtendOperationExecutor { - - public Executor(int position) { - super(position); - } - - @Override - public Iterator getIterator(MatchingFrame frame, ISearchContext context) { - Preconditions.checkState(frame.get(sourcePosition) instanceof EObject, "Only children of EObject elements are supported."); - EObject source = (EObject) frame.get(sourcePosition); - EObject container = source.eContainer(); - if (container == null) { - return Collections.emptyIterator(); - } else if (transitive) { - return new ParentIterator(source); - } else { - return Collections.singleton(container).iterator(); - } - } - - @Override - public ISearchOperation getOperation() { - return IterateOverContainers.this; - } - } - - private final int sourcePosition; - private final int containerPosition; - private final boolean transitive; - - /** - * - * @param containerPosition the position of the variable storing the found parent elements - * @param sourcePosition the position of the variable storing the selected element; must be bound - * @param transitive if false, only the direct container is returned; otherwise all containers - */ - public IterateOverContainers(int containerPosition, int sourcePosition, boolean transitive) { - this.containerPosition = containerPosition; - this.sourcePosition = sourcePosition; - this.transitive = transitive; - } - - - @Override - public ISearchOperationExecutor createExecutor() { - return new Executor(containerPosition); - } - - @Override - public String toString() { - return toString(Object::toString); - } - - @Override - public String toString(Function variableMapping) { - return "extend containment -"+variableMapping.apply(sourcePosition)+" <>--> +"+variableMapping.apply(containerPosition)+(transitive ? " transitively" : " directly"); - } - - @Override - public List getVariablePositions() { - return Arrays.asList(containerPosition, sourcePosition); - } - -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverEClassInstances.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverEClassInstances.java deleted file mode 100644 index 333ed1db..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverEClassInstances.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Zoltan Ujhelyi, Akos Horvath, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.extend; - -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.function.Function; - -import org.eclipse.emf.ecore.EClass; -import tools.refinery.viatra.runtime.emf.types.EClassTransitiveInstancesKey; -import tools.refinery.viatra.runtime.localsearch.MatchingFrame; -import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; -import tools.refinery.viatra.runtime.localsearch.operations.IIteratingSearchOperation; -import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContext; -import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; -import tools.refinery.viatra.runtime.matchers.tuple.Tuples; - -/** - * Iterates all available {@link EClass} instances using an {@link IQueryRuntimeContext VIATRA Base indexer}. It is - * assumed that the base indexer has been registered for the selected type. - * - * @author Zoltan Ujhelyi - * - */ -public class IterateOverEClassInstances implements IIteratingSearchOperation { - - private class Executor extends SingleValueExtendOperationExecutor { - - public Executor(int position) { - super(position); - } - - @Override - public Iterator getIterator(MatchingFrame frame, ISearchContext context) { - return context.getRuntimeContext().enumerateValues(type, indexerMask, Tuples.staticArityFlatTupleOf()).iterator(); - } - - @Override - public ISearchOperation getOperation() { - return IterateOverEClassInstances.this; - } - } - - private final EClass clazz; - private final EClassTransitiveInstancesKey type; - private static final TupleMask indexerMask = TupleMask.empty(1); - private final int position; - - public IterateOverEClassInstances(int position, EClass clazz) { - this.position = position; - this.clazz = clazz; - type = new EClassTransitiveInstancesKey(clazz); - } - - public EClass getClazz() { - return clazz; - } - - - @Override - public ISearchOperationExecutor createExecutor() { - return new Executor(position); - } - - @Override - public String toString() { - return toString(Object::toString); - } - - @Override - public String toString(Function variableMapping) { - return "extend "+clazz.getName()+"(-"+ variableMapping.apply(position)+") indexed"; - } - - @Override - public List getVariablePositions() { - return Collections.singletonList(position); - } - - /** - * @since 1.4 - */ - @Override - public IInputKey getIteratedInputKey() { - return type; - } - -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverEDatatypeInstances.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverEDatatypeInstances.java deleted file mode 100644 index 248a3d27..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverEDatatypeInstances.java +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Zoltan Ujhelyi, Akos Horvath, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.extend; - -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.function.Function; - -import org.eclipse.emf.ecore.EDataType; -import tools.refinery.viatra.runtime.emf.types.EDataTypeInSlotsKey; -import tools.refinery.viatra.runtime.localsearch.MatchingFrame; -import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; -import tools.refinery.viatra.runtime.localsearch.operations.IIteratingSearchOperation; -import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContext; -import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; -import tools.refinery.viatra.runtime.matchers.tuple.Tuples; - - -/** - * Iterates over all {@link EDataType} instances using an {@link IQueryRuntimeContext VIATRA Base indexer}. It is - * assumed that the indexer is initialized for the selected {@link EDataType}. - * - */ -public class IterateOverEDatatypeInstances implements IIteratingSearchOperation { - - private class Executor extends SingleValueExtendOperationExecutor { - - public Executor(int position) { - super(position); - } - - @Override - public Iterator getIterator(MatchingFrame frame, ISearchContext context) { - return context.getRuntimeContext().enumerateValues(type, indexerMask, Tuples.staticArityFlatTupleOf()).iterator(); - } - - @Override - public ISearchOperation getOperation() { - return IterateOverEDatatypeInstances.this; - } - } - - private final EDataType dataType; - private final EDataTypeInSlotsKey type; - private static final TupleMask indexerMask = TupleMask.empty(1); - private final int position; - - public IterateOverEDatatypeInstances(int position, EDataType dataType) { - this.position = position; - this.dataType = dataType; - type = new EDataTypeInSlotsKey(dataType); - } - - public EDataType getDataType() { - return dataType; - } - - @Override - public ISearchOperationExecutor createExecutor() { - return new Executor(position); - } - - @Override - public String toString() { - return toString(Object::toString); - } - - @Override - public String toString(Function variableMapping) { - return "extend "+dataType.getName()+"(-"+variableMapping.apply(position)+") indexed"; - } - - @Override - public List getVariablePositions() { - return Collections.singletonList(position); - } - - /** - * @since 1.4 - */ - @Override - public IInputKey getIteratedInputKey() { - return type; - } - - -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverEStructuralFeatureInstances.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverEStructuralFeatureInstances.java deleted file mode 100644 index 961939fa..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/IterateOverEStructuralFeatureInstances.java +++ /dev/null @@ -1,115 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Zoltan Ujhelyi, Akos Horvath, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.extend; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.function.Function; - -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.emf.types.EStructuralFeatureInstancesKey; -import tools.refinery.viatra.runtime.localsearch.MatchingFrame; -import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; -import tools.refinery.viatra.runtime.localsearch.operations.IIteratingSearchOperation; -import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContext; -import tools.refinery.viatra.runtime.matchers.tuple.Tuple; -import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; -import tools.refinery.viatra.runtime.matchers.tuple.Tuples; - -/** - * Iterates all available {@link EStructuralFeature} elements using an {@link IQueryRuntimeContext VIATRA Base - * indexer}. It is assumed that the base indexer has been registered for the selected reference type. - * - */ -public class IterateOverEStructuralFeatureInstances implements IIteratingSearchOperation{ - - private class Executor implements ISearchOperationExecutor { - private Iterator it; - - @Override - public void onBacktrack(MatchingFrame frame, ISearchContext context) { - frame.setValue(sourcePosition, null); - frame.setValue(targetPosition, null); - it = null; - } - - @Override - public void onInitialize(MatchingFrame frame, ISearchContext context) { - Iterable tuples = context.getRuntimeContext().enumerateTuples(type, indexerMask, Tuples.staticArityFlatTupleOf()); - - it = tuples.iterator(); - } - - @Override - public boolean execute(MatchingFrame frame, ISearchContext context) { - if (it.hasNext()) { - final Tuple next = it.next(); - frame.setValue(sourcePosition, next.get(0)); - frame.setValue(targetPosition, next.get(1)); - return true; - } else { - return false; - } - } - - @Override - public ISearchOperation getOperation() { - return IterateOverEStructuralFeatureInstances.this; - } - } - - private final EStructuralFeature feature; - private final int sourcePosition; - private final int targetPosition; - private final EStructuralFeatureInstancesKey type; - private static final TupleMask indexerMask = TupleMask.empty(2); - - public IterateOverEStructuralFeatureInstances(int sourcePosition, int targetPosition, EStructuralFeature feature) { - this.sourcePosition = sourcePosition; - this.targetPosition = targetPosition; - this.feature = feature; - type = new EStructuralFeatureInstancesKey(feature); - } - - public EStructuralFeature getFeature() { - return feature; - } - - @Override - public ISearchOperationExecutor createExecutor() { - return new Executor(); - } - - @Override - public String toString() { - return toString(Object::toString); - } - - @Override - public String toString(Function variableMapping) { - return "extend "+feature.getContainerClass().getSimpleName()+"."+feature.getName()+"(-"+variableMapping.apply(sourcePosition)+", -"+variableMapping.apply(targetPosition)+") indexed"; - } - - @Override - public List getVariablePositions() { - return Arrays.asList(sourcePosition, targetPosition); - } - - /** - * @since 1.4 - */ - @Override - public IInputKey getIteratedInputKey() { - return type; - } - -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/nobase/AbstractIteratingExtendOperationExecutor.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/nobase/AbstractIteratingExtendOperationExecutor.java deleted file mode 100644 index 954d4c88..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/nobase/AbstractIteratingExtendOperationExecutor.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Grill Balázs, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.extend.nobase; - -import java.util.Collections; -import java.util.Spliterator; -import java.util.Spliterators; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -import org.eclipse.emf.common.notify.Notifier; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; -import tools.refinery.viatra.runtime.emf.EMFScope; -import tools.refinery.viatra.runtime.localsearch.operations.extend.SingleValueExtendOperationExecutor; - -/** - * This abstract class provides a utility method for extenders to iterate over the given scope. - * - * @author Grill Balázs - * @noextend This class is not intended to be subclassed by clients. - * - */ -abstract class AbstractIteratingExtendOperationExecutor extends SingleValueExtendOperationExecutor { - - private final EMFScope scope; - - public AbstractIteratingExtendOperationExecutor(int position, EMFScope scope) { - super(position); - this.scope = scope; - } - - protected Stream getModelContents() { - return scope.getScopeRoots().stream().map(input -> { - if (input instanceof ResourceSet) { - return ((ResourceSet) input).getAllContents(); - } else if (input instanceof Resource) { - return ((Resource) input).getAllContents(); - } else if (input instanceof EObject) { - return ((EObject) input).eAllContents(); - } - return Collections. emptyIterator(); - }).map(i -> StreamSupport.stream(Spliterators.spliteratorUnknownSize(i, Spliterator.ORDERED), false)) - .flatMap(i -> i); - } - -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/nobase/ExtendToEStructuralFeatureSource.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/nobase/ExtendToEStructuralFeatureSource.java deleted file mode 100644 index fc79640b..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/nobase/ExtendToEStructuralFeatureSource.java +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Marton Bur, Zoltan Ujhelyi, Akos Horvath, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.extend.nobase; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.function.Function; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.base.api.NavigationHelper; -import tools.refinery.viatra.runtime.localsearch.MatchingFrame; -import tools.refinery.viatra.runtime.localsearch.exceptions.LocalSearchException; -import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; -import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; -import tools.refinery.viatra.runtime.localsearch.operations.extend.SingleValueExtendOperationExecutor; - -/** - * Iterates over all sources of {@link EStructuralFeature} using an {@link NavigationHelper VIATRA Base indexer}. - * It is assumed that the indexer is initialized for the selected {@link EStructuralFeature}. - * - */ -public class ExtendToEStructuralFeatureSource implements ISearchOperation { - - private class Executor extends SingleValueExtendOperationExecutor { - - private Executor() { - super(sourcePosition); - } - - @SuppressWarnings("unchecked") - @Override - public Iterator getIterator(MatchingFrame frame, ISearchContext context) { - if(!(feature instanceof EReference)){ - throw new LocalSearchException("Without base index, inverse navigation only possible along " - + "EReferences with defined EOpposite."); - } - EReference oppositeFeature = ((EReference)feature).getEOpposite(); - if(oppositeFeature == null){ - throw new LocalSearchException("Feature has no EOpposite, so cannot do inverse navigation " + feature.toString()); - } - try { - final EObject value = (EObject) frame.getValue(targetPosition); - if(! oppositeFeature.getEContainingClass().isSuperTypeOf(value.eClass()) ){ - // TODO planner should ensure the proper supertype relation - return Collections.emptyIterator(); - } - final Object featureValue = value.eGet(oppositeFeature); - if (oppositeFeature.isMany()) { - if (featureValue != null) { - final Collection objectCollection = (Collection) featureValue; - return objectCollection.iterator(); - } else { - return Collections.emptyIterator(); - } - } else { - if (featureValue != null) { - return Collections.singleton(featureValue).iterator(); - } else { - return Collections.emptyIterator(); - } - } - } catch (ClassCastException e) { - throw new LocalSearchException("Invalid feature target in parameter" + Integer.toString(targetPosition), e); - } - } - - @Override - public ISearchOperation getOperation() { - return ExtendToEStructuralFeatureSource.this; - } - } - - private int targetPosition; - private EStructuralFeature feature; - private int sourcePosition; - - public ExtendToEStructuralFeatureSource(int sourcePosition, int targetPosition, EStructuralFeature feature) { - this.sourcePosition = sourcePosition; - this.targetPosition = targetPosition; - this.feature = feature; - } - - public EStructuralFeature getFeature() { - return feature; - } - - @Override - public ISearchOperationExecutor createExecutor() { - return new Executor(); - } - - @Override - public String toString() { - return toString(Object::toString); - } - - @Override - public String toString(Function variableMapping) { - return "extend "+feature.getContainerClass().getSimpleName()+"."+feature.getName()+"(-"+variableMapping.apply(sourcePosition)+", +"+variableMapping.apply(targetPosition)+") iterating"; - } - - @Override - public List getVariablePositions() { - return Arrays.asList(sourcePosition, targetPosition); - } - -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/nobase/IterateOverEClassInstances.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/nobase/IterateOverEClassInstances.java deleted file mode 100644 index 0a4c46ec..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/nobase/IterateOverEClassInstances.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Marton Bur, Zoltan Ujhelyi, Akos Horvath, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.extend.nobase; - -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.function.Function; - -import org.eclipse.emf.common.notify.Notifier; -import org.eclipse.emf.ecore.EClass; -import tools.refinery.viatra.runtime.base.api.NavigationHelper; -import tools.refinery.viatra.runtime.emf.EMFScope; -import tools.refinery.viatra.runtime.emf.types.EClassTransitiveInstancesKey; -import tools.refinery.viatra.runtime.localsearch.MatchingFrame; -import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; -import tools.refinery.viatra.runtime.localsearch.operations.IIteratingSearchOperation; -import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; -import tools.refinery.viatra.runtime.matchers.context.IInputKey; - -/** - * Iterates all available {@link EClass} instances without using an {@link NavigationHelper VIATRA Base indexer}. - * - * @author Zoltan Ujhelyi - */ -public class IterateOverEClassInstances implements IIteratingSearchOperation { - - private class Executor extends AbstractIteratingExtendOperationExecutor { - - public Executor(int position, EMFScope scope) { - super(position, scope); - } - - @Override - public Iterator getIterator(MatchingFrame frame, ISearchContext context) { - return getModelContents().filter(clazz::isInstance).iterator(); - } - - @Override - public ISearchOperation getOperation() { - return IterateOverEClassInstances.this; - } - } - - private final int position; - private final EClass clazz; - private final EMFScope scope; - - public IterateOverEClassInstances(int position, EClass clazz, EMFScope scope) { - this.position = position; - this.clazz = clazz; - this.scope = scope; - } - - public EClass getClazz() { - return clazz; - } - - @Override - public ISearchOperationExecutor createExecutor() { - return new Executor(position, scope); - } - - @Override - public String toString() { - return toString(Object::toString); - } - - @Override - public String toString(Function variableMapping) { - return "extend "+clazz.getName()+"(-"+ variableMapping.apply(position)+") iterating"; - } - - @Override - public List getVariablePositions() { - return Collections.singletonList(position); - } - - /** - * @since 1.4 - */ - @Override - public IInputKey getIteratedInputKey() { - return new EClassTransitiveInstancesKey(clazz); - } - -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/nobase/IterateOverEDatatypeInstances.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/nobase/IterateOverEDatatypeInstances.java deleted file mode 100644 index 999e0a48..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/operations/extend/nobase/IterateOverEDatatypeInstances.java +++ /dev/null @@ -1,123 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Marton Bur, Zoltan Ujhelyi, Akos Horvath, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.operations.extend.nobase; - -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.eclipse.emf.ecore.EAttribute; -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EDataType; -import org.eclipse.emf.ecore.EObject; -import tools.refinery.viatra.runtime.base.api.NavigationHelper; -import tools.refinery.viatra.runtime.emf.EMFScope; -import tools.refinery.viatra.runtime.emf.types.EDataTypeInSlotsKey; -import tools.refinery.viatra.runtime.localsearch.MatchingFrame; -import tools.refinery.viatra.runtime.localsearch.matcher.ISearchContext; -import tools.refinery.viatra.runtime.localsearch.operations.IIteratingSearchOperation; -import tools.refinery.viatra.runtime.localsearch.operations.ISearchOperation; -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.tuple.Tuple; -import tools.refinery.viatra.runtime.matchers.tuple.Tuples; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory; - -/** - * Iterates over all {@link EDataType} instances without using an {@link NavigationHelper VIATRA Base indexer}. - * - */ -public class IterateOverEDatatypeInstances implements IIteratingSearchOperation { - - private class Executor extends AbstractIteratingExtendOperationExecutor { - - public Executor(int position, EMFScope scope) { - super(position, scope); - } - - @Override - public Iterator getIterator(MatchingFrame frame, final ISearchContext context) { - return getModelContents().filter(EObject.class::isInstance).map(EObject.class::cast) - .map(input -> doGetEAttributes(input.eClass(), context) - .map(attribute -> { - if (attribute.isMany()) { - return ((List) input.eGet(attribute)).stream(); - } else { - Object o = input.eGet(attribute); - return o == null ? Stream.empty() : Stream.of(o); - } - })) - .flatMap(i -> i) - .flatMap(i -> i) - .iterator(); - } - - @Override - public ISearchOperation getOperation() { - return IterateOverEDatatypeInstances.this; - } - } - - private final EDataType dataType; - private final int position; - private final EMFScope scope; - - public IterateOverEDatatypeInstances(int position, EDataType dataType, EMFScope scope) { - this.position = position; - this.dataType = dataType; - this.scope = scope; - } - - protected Stream doGetEAttributes(EClass eclass, ISearchContext context){ - @SuppressWarnings({ "unchecked"}) - Map> cache = context.accessBackendLevelCache(getClass(), Map.class, CollectionsFactory::createMap); - Tuple compositeKey = Tuples.staticArityFlatTupleOf(dataType, eclass); - return cache.computeIfAbsent(compositeKey, k -> - eclass.getEAllAttributes().stream().filter(input -> Objects.equals(input.getEType(), dataType)).collect(Collectors.toSet()) - ).stream(); - } - - public EDataType getDataType() { - return dataType; - } - - @Override - public ISearchOperationExecutor createExecutor() { - return new Executor(position, scope); - } - - @Override - public String toString() { - return toString(Object::toString); - } - - @Override - public String toString(Function variableMapping) { - return "extend "+dataType.getName()+"(-"+variableMapping.apply(position)+") iterating"; - } - - @Override - public List getVariablePositions() { - return Collections.singletonList(position); - } - - /** - * @since 1.4 - */ - @Override - public IInputKey getIteratedInputKey() { - return new EDataTypeInSlotsKey(dataType); - } - -} diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/planner/PConstraintInfoInferrer.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/planner/PConstraintInfoInferrer.java index 96fda930..eeac07ce 100644 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/planner/PConstraintInfoInferrer.java +++ b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/planner/PConstraintInfoInferrer.java @@ -3,40 +3,18 @@ * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-v20.html. - * + * * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ package tools.refinery.viatra.runtime.localsearch.planner; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.eclipse.emf.ecore.EReference; -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.base.api.BaseIndexOptions; -import tools.refinery.viatra.runtime.base.comprehension.EMFModelComprehension; -import tools.refinery.viatra.runtime.emf.types.EStructuralFeatureInstancesKey; import tools.refinery.viatra.runtime.localsearch.planner.cost.IConstraintEvaluationContext; import tools.refinery.viatra.runtime.matchers.backend.ResultProviderRequestor; import tools.refinery.viatra.runtime.matchers.context.IInputKey; import tools.refinery.viatra.runtime.matchers.context.IQueryBackendContext; import tools.refinery.viatra.runtime.matchers.psystem.PConstraint; import tools.refinery.viatra.runtime.matchers.psystem.PVariable; -import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.AggregatorConstraint; -import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.ExportedParameter; -import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.ExpressionEvaluation; -import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.Inequality; -import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.PatternMatchCounter; -import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.TypeFilterConstraint; +import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.*; import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.AbstractTransitiveClosure; import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.ConstantValue; import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.PositivePatternCall; @@ -46,39 +24,42 @@ import tools.refinery.viatra.runtime.matchers.psystem.queries.PParameterDirectio import tools.refinery.viatra.runtime.matchers.tuple.Tuple; import tools.refinery.viatra.runtime.matchers.util.Sets; +import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + /** * @author Grill Balázs * @noreference This class is not intended to be referenced by clients. */ class PConstraintInfoInferrer { - + private static final Predicate SINGLE_USE_VARIABLE = input -> input != null && input.getReferringConstraints().size() == 1; private final boolean useIndex; private final Function costFunction; - private final EMFModelComprehension modelComprehension; private final IQueryBackendContext context; private final ResultProviderRequestor resultRequestor; - - public PConstraintInfoInferrer(boolean useIndex, - IQueryBackendContext backendContext, + + public PConstraintInfoInferrer(boolean useIndex, + IQueryBackendContext backendContext, ResultProviderRequestor resultRequestor, Function costFunction) { this.useIndex = useIndex; this.context = backendContext; this.resultRequestor = resultRequestor; this.costFunction = costFunction; - this.modelComprehension = new EMFModelComprehension(new BaseIndexOptions()); } - - + + /** * Create all possible application condition for all constraint - * + * * @param constraintSet the set of constraints - * @param runtimeContext the model dependent runtime contest * @return a collection of the wrapper PConstraintInfo objects with all the allowed application conditions */ public List createPConstraintInfos(Set constraintSet) { @@ -106,7 +87,7 @@ class PConstraintInfoInferrer { } else if (pConstraint instanceof AggregatorConstraint){ createConstraintInfoAggregatorConstraint(resultList, pConstraint, ((AggregatorConstraint) pConstraint).getResultVariable()); } else if (pConstraint instanceof PatternMatchCounter){ - createConstraintInfoAggregatorConstraint(resultList, pConstraint, ((PatternMatchCounter) pConstraint).getResultVariable()); + createConstraintInfoAggregatorConstraint(resultList, pConstraint, ((PatternMatchCounter) pConstraint).getResultVariable()); } else if (pConstraint instanceof PositivePatternCall){ createConstraintInfoPositivePatternCall(resultList, (PositivePatternCall) pConstraint); } else if (pConstraint instanceof AbstractTransitiveClosure) { @@ -115,10 +96,10 @@ class PConstraintInfoInferrer { createConstraintInfoGeneric(resultList, pConstraint); } } - - private void createConstraintInfoConstantValue(List resultList, + + private void createConstraintInfoConstantValue(List resultList, ConstantValue pConstraint) { - // A ConstantValue constraint has a single variable, which is allowed to be unbound + // A ConstantValue constraint has a single variable, which is allowed to be unbound // (extending through ConstantValue is considered a cheap operation) Set affectedVariables = pConstraint.getAffectedVariables(); Set> bindings = Sets.powerSet(affectedVariables); @@ -126,7 +107,7 @@ class PConstraintInfoInferrer { } - private void createConstraintInfoPositivePatternCall(List resultList, + private void createConstraintInfoPositivePatternCall(List resultList, PositivePatternCall pCall) { // A pattern call can have any of its variables unbound Set affectedVariables = pCall.getAffectedVariables(); @@ -147,23 +128,23 @@ class PConstraintInfoInferrer { case OUT: default: break; - + } } Iterable> bindings = Sets.powerSet(inoutVariables).stream() .map(input -> Stream.concat(input.stream(), inVariables.stream()).collect(Collectors.toSet())) .collect(Collectors.toSet()); - + doCreateConstraintInfos(resultList, pCall, affectedVariables, bindings); } - - private void createConstraintInfoBinaryTransitiveClosure(List resultList, + + private void createConstraintInfoBinaryTransitiveClosure(List resultList, AbstractTransitiveClosure closure) { // A pattern call can have any of its variables unbound - + List parameters = closure.getReferredQuery().getParameters(); Tuple variables = closure.getVariablesTuple(); - + Set> bindings = new HashSet<>(); PVariable firstVariable = (PVariable) variables.get(0); PVariable secondVariable = (PVariable) variables.get(1); @@ -177,20 +158,20 @@ class PConstraintInfoInferrer { if (parameters.get(1).getDirection() != PParameterDirection.IN) { bindings.add(Collections.singleton(firstVariable)); } - + doCreateConstraintInfos(resultList, closure, closure.getAffectedVariables(), bindings); } - - - private void createConstraintInfoExportedParameter(List resultList, + + + private void createConstraintInfoExportedParameter(List resultList, ExportedParameter parameter) { // In case of an exported parameter constraint, the parameter must be bound in order to execute Set affectedVariables = parameter.getAffectedVariables(); doCreateConstraintInfos(resultList, parameter, affectedVariables, Collections.singleton(affectedVariables)); } - - private void createConstraintInfoExpressionEvaluation(List resultList, + + private void createConstraintInfoExpressionEvaluation(List resultList, ExpressionEvaluation expressionEvaluation) { // An expression evaluation can only have its output variable unbound. All other variables shall be bound PVariable output = expressionEvaluation.getOutputVariable(); @@ -203,41 +184,41 @@ class PConstraintInfoInferrer { doCreateConstraintInfos(resultList, expressionEvaluation, affectedVariables, bindings); } - private void createConstraintInfoTypeFilterConstraint(List resultList, + private void createConstraintInfoTypeFilterConstraint(List resultList, TypeFilterConstraint filter){ // In case of type filter, all affected variables must be bound in order to execute Set affectedVariables = filter.getAffectedVariables(); doCreateConstraintInfos(resultList, filter, affectedVariables, Collections.singleton(affectedVariables)); } - - private void createConstraintInfoInequality(List resultList, + + private void createConstraintInfoInequality(List resultList, Inequality inequality){ // In case of inequality, all affected variables must be bound in order to execute Set affectedVariables = inequality.getAffectedVariables(); doCreateConstraintInfos(resultList, inequality, affectedVariables, Collections.singleton(affectedVariables)); } - - private void createConstraintInfoAggregatorConstraint(List resultList, + + private void createConstraintInfoAggregatorConstraint(List resultList, PConstraint pConstraint, PVariable resultVariable){ Set affectedVariables = pConstraint.getAffectedVariables(); - + // The only variables which can be unbound are single-use - Set canBeUnboundVariables = + Set canBeUnboundVariables = Stream.concat(Stream.of(resultVariable), affectedVariables.stream().filter(SINGLE_USE_VARIABLE)).collect(Collectors.toSet()); - + Set> bindings = calculatePossibleBindings(canBeUnboundVariables, affectedVariables); - + doCreateConstraintInfos(resultList, pConstraint, affectedVariables, bindings); } - + /** - * + * * @param canBeUnboundVariables Variables which are allowed to be unbound * @param affectedVariables All affected variables * @return The set of possible bound variable sets */ private Set> calculatePossibleBindings(Set canBeUnboundVariables, Set affectedVariables){ - final Set mustBindVariables = affectedVariables.stream().filter(input -> !canBeUnboundVariables.contains(input)).collect(Collectors.toSet()); + final Set mustBindVariables = affectedVariables.stream().filter(input -> !canBeUnboundVariables.contains(input)).collect(Collectors.toSet()); return Sets.powerSet(canBeUnboundVariables).stream() .map(input -> { //some variables have to be bound before executing this constraint @@ -247,33 +228,23 @@ class PConstraintInfoInferrer { }) .collect(Collectors.toSet()); } - + private void createConstraintInfoGeneric(List resultList, PConstraint pConstraint){ Set affectedVariables = pConstraint.getAffectedVariables(); - + // The only variables which can be unbound are single use variables Set canBeUnboundVariables = affectedVariables.stream().filter(SINGLE_USE_VARIABLE).collect(Collectors.toSet()); - + Set> bindings = calculatePossibleBindings(canBeUnboundVariables, affectedVariables); - + doCreateConstraintInfos(resultList, pConstraint, affectedVariables, bindings); } - - private boolean canPerformInverseNavigation(EStructuralFeature feature){ - return ( // Feature has opposite (this only possible for references) - hasEOpposite(feature) - || - (feature instanceof EReference) && ((EReference)feature).isContainment() - || ( // Indexing is enabled, and the feature can be indexed (not a non-well-behaving derived feature). - useIndex && modelComprehension.representable(feature) - )); - } - - private void createConstraintInfoTypeConstraint(List resultList, + + private void createConstraintInfoTypeConstraint(List resultList, TypeConstraint typeConstraint) { Set affectedVariables = typeConstraint.getAffectedVariables(); Set> bindings = null; - + IInputKey inputKey = typeConstraint.getSupplierKey(); if(inputKey.isEnumerable()){ bindings = Sets.powerSet(affectedVariables); @@ -281,23 +252,15 @@ class PConstraintInfoInferrer { // For not enumerable types, this constraint can only be a check bindings = Collections.singleton(affectedVariables); } - - if(inputKey instanceof EStructuralFeatureInstancesKey){ - final EStructuralFeature feature = ((EStructuralFeatureInstancesKey) inputKey).getEmfKey(); - if(!canPerformInverseNavigation(feature)){ - // When inverse navigation is not allowed or not possible, filter out operation masks, where - // the first variable would be free AND the feature is an EReference and has no EOpposite - bindings = excludeUnnavigableOperationMasks(typeConstraint, bindings); - } - } + doCreateConstraintInfos(resultList, typeConstraint, affectedVariables, bindings); } - + private void doCreateConstraintInfos(List constraintInfos, PConstraint pConstraint, Set affectedVariables, Iterable> bindings) { Set sameWithDifferentBindings = new HashSet<>(); for (Set boundVariables : bindings) { - + PConstraintInfo info = new PConstraintInfo(pConstraint, boundVariables, affectedVariables.stream().filter(input -> !boundVariables.contains(input)).collect(Collectors.toSet()), sameWithDifferentBindings, context, resultRequestor, costFunction); @@ -305,22 +268,11 @@ class PConstraintInfoInferrer { sameWithDifferentBindings.add(info); } } - + private Set> excludeUnnavigableOperationMasks(TypeConstraint typeConstraint, Set> bindings) { PVariable firstVariable = typeConstraint.getVariableInTuple(0); return bindings.stream().filter( boundVariablesSet -> (boundVariablesSet.isEmpty() || boundVariablesSet.contains(firstVariable))) .collect(Collectors.toSet()); } - - private boolean hasEOpposite(EStructuralFeature feature) { - if(feature instanceof EReference){ - EReference eOpposite = ((EReference) feature).getEOpposite(); - if(eOpposite != null){ - return true; - } - } - return false; - } - } diff --git a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/planner/compiler/EMFOperationCompiler.java b/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/planner/compiler/EMFOperationCompiler.java deleted file mode 100644 index 7fd86f3c..00000000 --- a/subprojects/viatra-runtime-localsearch/src/main/java/tools/refinery/viatra/runtime/localsearch/planner/compiler/EMFOperationCompiler.java +++ /dev/null @@ -1,198 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2017, Zoltan Ujhelyi, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.localsearch.planner.compiler; - -import java.util.Map; - -import org.eclipse.emf.ecore.EReference; -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.emf.EMFQueryRuntimeContext; -import tools.refinery.viatra.runtime.emf.types.EClassTransitiveInstancesKey; -import tools.refinery.viatra.runtime.emf.types.EClassUnscopedTransitiveInstancesKey; -import tools.refinery.viatra.runtime.emf.types.EDataTypeInSlotsKey; -import tools.refinery.viatra.runtime.emf.types.EStructuralFeatureInstancesKey; -import tools.refinery.viatra.runtime.localsearch.operations.check.InstanceOfClassCheck; -import tools.refinery.viatra.runtime.localsearch.operations.check.InstanceOfDataTypeCheck; -import tools.refinery.viatra.runtime.localsearch.operations.check.InstanceOfJavaClassCheck; -import tools.refinery.viatra.runtime.localsearch.operations.check.StructuralFeatureCheck; -import tools.refinery.viatra.runtime.localsearch.operations.check.nobase.ScopeCheck; -import tools.refinery.viatra.runtime.localsearch.operations.extend.ExtendToEStructuralFeatureSource; -import tools.refinery.viatra.runtime.localsearch.operations.extend.ExtendToEStructuralFeatureTarget; -import tools.refinery.viatra.runtime.localsearch.operations.extend.IterateOverContainers; -import tools.refinery.viatra.runtime.localsearch.operations.extend.IterateOverEClassInstances; -import tools.refinery.viatra.runtime.localsearch.operations.extend.IterateOverEDatatypeInstances; -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContext; -import tools.refinery.viatra.runtime.matchers.context.common.JavaTransitiveInstancesKey; -import tools.refinery.viatra.runtime.matchers.planning.QueryProcessingException; -import tools.refinery.viatra.runtime.matchers.psystem.PVariable; -import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.TypeFilterConstraint; -import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.TypeConstraint; -import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; - -/** - * Operation compiler implementation that uses EMF-specific operations. - * - * @author Zoltan Ujhelyi - * @since 1.7 - * - */ -public class EMFOperationCompiler extends AbstractOperationCompiler { - - private boolean baseIndexAvailable; - - private final EMFQueryRuntimeContext runtimeContext; - - public EMFOperationCompiler(IQueryRuntimeContext runtimeContext) { - this(runtimeContext, false); - } - - public EMFOperationCompiler(IQueryRuntimeContext runtimeContext, boolean baseIndexAvailable) { - super(runtimeContext); - this.runtimeContext = (EMFQueryRuntimeContext) runtimeContext; - this.baseIndexAvailable = baseIndexAvailable; - } - - @Override - protected void createCheck(TypeFilterConstraint typeConstraint, Map variableMapping) { - final IInputKey inputKey = typeConstraint.getInputKey(); - if (inputKey instanceof JavaTransitiveInstancesKey) { - doCreateInstanceofJavaTypeCheck((JavaTransitiveInstancesKey) inputKey, variableMapping.get(typeConstraint.getVariablesTuple().get(0))); - } else if (inputKey instanceof EDataTypeInSlotsKey) { // TODO probably only occurs as TypeConstraint - doCreateInstanceofDatatypeCheck((EDataTypeInSlotsKey) inputKey, variableMapping.get(typeConstraint.getVariablesTuple().get(0))); - } else if (inputKey instanceof EClassUnscopedTransitiveInstancesKey) { - doCreateInstanceofUnscopedClassCheck((EClassUnscopedTransitiveInstancesKey) inputKey, variableMapping.get(typeConstraint.getVariablesTuple().get(0))); - } else { - String msg = UNSUPPORTED_TYPE_MESSAGE + inputKey; - throw new QueryProcessingException(msg, null, msg, null); - } - } - - @Override - protected void createCheck(TypeConstraint typeConstraint, Map variableMapping) { - final IInputKey inputKey = typeConstraint.getSupplierKey(); - if (inputKey instanceof EClassTransitiveInstancesKey) { - doCreateInstanceofClassCheck((EClassTransitiveInstancesKey)inputKey, variableMapping.get(typeConstraint.getVariablesTuple().get(0))); - } else if (inputKey instanceof EStructuralFeatureInstancesKey) { - int sourcePosition = variableMapping.get(typeConstraint.getVariablesTuple().get(0)); - int targetPosition = variableMapping.get(typeConstraint.getVariablesTuple().get(1)); - operations.add(new StructuralFeatureCheck(sourcePosition, targetPosition, - ((EStructuralFeatureInstancesKey) inputKey).getEmfKey())); - } else if (inputKey instanceof EDataTypeInSlotsKey) { - doCreateInstanceofDatatypeCheck((EDataTypeInSlotsKey) inputKey, variableMapping.get(typeConstraint.getVariablesTuple().get(0))); - } else { - String msg = UNSUPPORTED_TYPE_MESSAGE + inputKey; - throw new QueryProcessingException(msg, null, msg, null); - } - } - - @Override - protected void createUnaryTypeCheck(IInputKey inputKey, int position) { - if (inputKey instanceof EClassTransitiveInstancesKey) { - doCreateInstanceofClassCheck((EClassTransitiveInstancesKey)inputKey, position); - } else if (inputKey instanceof EClassUnscopedTransitiveInstancesKey) { - doCreateInstanceofUnscopedClassCheck((EClassUnscopedTransitiveInstancesKey)inputKey, position); - } else if (inputKey instanceof EDataTypeInSlotsKey) { - doCreateInstanceofDatatypeCheck((EDataTypeInSlotsKey) inputKey, position); - } else if (inputKey instanceof JavaTransitiveInstancesKey) { - doCreateInstanceofJavaTypeCheck((JavaTransitiveInstancesKey) inputKey, position); - } else { - String msg = UNSUPPORTED_TYPE_MESSAGE + inputKey; - throw new QueryProcessingException(msg, null, msg, null); - } - } - - private void doCreateInstanceofClassCheck(EClassTransitiveInstancesKey inputKey, int position) { - operations.add(new InstanceOfClassCheck(position, inputKey.getEmfKey())); - operations.add(new ScopeCheck(position, runtimeContext.getEmfScope())); - } - - private void doCreateInstanceofUnscopedClassCheck(EClassUnscopedTransitiveInstancesKey inputKey, int position) { - operations.add(new InstanceOfClassCheck(position, inputKey.getEmfKey())); - } - - private void doCreateInstanceofDatatypeCheck(EDataTypeInSlotsKey inputKey, int position) { - operations.add(new InstanceOfDataTypeCheck(position, inputKey.getEmfKey())); - } - private void doCreateInstanceofJavaTypeCheck(JavaTransitiveInstancesKey inputKey, int position) { - operations.add(new InstanceOfJavaClassCheck(position, inputKey.getInstanceClass())); - } - - @Override - public void createExtend(TypeConstraint typeConstraint, Map variableMapping) { - final IInputKey inputKey = typeConstraint.getSupplierKey(); - if (inputKey instanceof EDataTypeInSlotsKey) { - if(baseIndexAvailable){ - operations.add(new IterateOverEDatatypeInstances(variableMapping.get(typeConstraint.getVariableInTuple(0)), ((EDataTypeInSlotsKey) inputKey).getEmfKey())); - } else { - int position = variableMapping.get(typeConstraint.getVariableInTuple(0)); - operations - .add(new tools.refinery.viatra.runtime.localsearch.operations.extend.nobase.IterateOverEDatatypeInstances(position, - ((EDataTypeInSlotsKey) inputKey).getEmfKey(), runtimeContext.getEmfScope())); - operations.add(new ScopeCheck(position, runtimeContext.getEmfScope())); - } - } else if (inputKey instanceof EClassTransitiveInstancesKey) { - if(baseIndexAvailable){ - operations.add(new IterateOverEClassInstances(variableMapping.get(typeConstraint.getVariableInTuple(0)), - ((EClassTransitiveInstancesKey) inputKey).getEmfKey())); - } else { - int position = variableMapping.get(typeConstraint.getVariableInTuple(0)); - operations - .add(new tools.refinery.viatra.runtime.localsearch.operations.extend.nobase.IterateOverEClassInstances( - position, - ((EClassTransitiveInstancesKey) inputKey).getEmfKey(), runtimeContext.getEmfScope())); - operations.add(new ScopeCheck(position, runtimeContext.getEmfScope())); - } - } else if (inputKey instanceof EStructuralFeatureInstancesKey) { - final EStructuralFeature feature = ((EStructuralFeatureInstancesKey) inputKey).getEmfKey(); - - int sourcePosition = variableMapping.get(typeConstraint.getVariablesTuple().get(0)); - int targetPosition = variableMapping.get(typeConstraint.getVariablesTuple().get(1)); - - boolean fromBound = variableBindings.get(typeConstraint).contains(sourcePosition); - boolean toBound = variableBindings.get(typeConstraint).contains(targetPosition); - - if (fromBound && !toBound) { - operations.add(new ExtendToEStructuralFeatureTarget(sourcePosition, targetPosition, feature)); - operations.add(new ScopeCheck(targetPosition, runtimeContext.getEmfScope())); - } else if(!fromBound && toBound){ - if (feature instanceof EReference && ((EReference)feature).isContainment()) { - // The iterate is also used to traverse a single container (third parameter) - operations.add(new IterateOverContainers(sourcePosition, targetPosition, false)); - operations.add(new ScopeCheck(sourcePosition, runtimeContext.getEmfScope())); - } else if(baseIndexAvailable){ - TupleMask mask = TupleMask.fromSelectedIndices(variableMapping.size(), new int[] {targetPosition}); - operations.add(new ExtendToEStructuralFeatureSource(sourcePosition, targetPosition, feature, mask)); - } else { - operations.add(new tools.refinery.viatra.runtime.localsearch.operations.extend.nobase.ExtendToEStructuralFeatureSource( - sourcePosition, targetPosition, feature)); - operations.add(new ScopeCheck(sourcePosition, runtimeContext.getEmfScope())); - } - } else { - // TODO Elaborate solution based on the navigability of edges - // As of now a static solution is implemented - if (baseIndexAvailable) { - operations.add(new IterateOverEClassInstances(sourcePosition, feature.getEContainingClass())); - operations.add(new ExtendToEStructuralFeatureTarget(sourcePosition, targetPosition, feature)); - } else { - operations - .add(new tools.refinery.viatra.runtime.localsearch.operations.extend.nobase.IterateOverEClassInstances( - sourcePosition, feature.getEContainingClass(), runtimeContext.getEmfScope())); - operations.add(new ScopeCheck(sourcePosition, runtimeContext.getEmfScope())); - operations.add(new ExtendToEStructuralFeatureTarget(sourcePosition, targetPosition, feature)); - operations.add(new ScopeCheck(targetPosition, runtimeContext.getEmfScope())); - } - } - - } else { - throw new IllegalArgumentException(UNSUPPORTED_TYPE_MESSAGE + inputKey); - } - } - -} diff --git a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/IStorageBackend.java b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/IStorageBackend.java deleted file mode 100644 index 16f40358..00000000 --- a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/IStorageBackend.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.matchers.scopes; - -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.scopes.tables.ITableContext; -import tools.refinery.viatra.runtime.matchers.scopes.tables.ITableWriterBinary; -import tools.refinery.viatra.runtime.matchers.scopes.tables.ITableWriterUnary; - -/** - * An abstract storage backend that instantiates tables and coordinates transactions. - * - *

EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will - * work or that it will remain the same. - * - * @author Gabor Bergmann - * - * @since 2.1 - */ -public interface IStorageBackend { - - - /** - * Marks the beginning of a transaction. - * In transaction mode, table updates may be temporarily delayed ({@link tools.refinery.viatra.runtime.matchers.scopes.tables.IIndexTable} methods may return stale answers) for better performance. - */ - void startTransaction(); - /** - * Marks the end of a transaction. - * Any updates delayed during the transaction must now be flushed. - */ - void finishTransaction(); - - /** - * Creates an index table for a simple value set. - * @param unique client promises to only insert a given tuple with multiplicity one - */ - ITableWriterUnary.Table createUnaryTable(IInputKey key, ITableContext tableContext, boolean unique); - /** - * Creates an index table for a simple source-target bidirectional mapping. - * @param unique client promises to only insert a given tuple with multiplicity one - */ - ITableWriterBinary.Table createBinaryTable(IInputKey key, ITableContext tableContext, boolean unique); - - -} diff --git a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/SimpleLocalStorageBackend.java b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/SimpleLocalStorageBackend.java deleted file mode 100644 index fd1f7b7e..00000000 --- a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/SimpleLocalStorageBackend.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.matchers.scopes; - -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.scopes.tables.ITableContext; -import tools.refinery.viatra.runtime.matchers.scopes.tables.SimpleBinaryTable; -import tools.refinery.viatra.runtime.matchers.scopes.tables.SimpleUnaryTable; - -/** - * Basic storage backend implementation based on local collections. - * - *

EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will - * work or that it will remain the same. - * - * @author Gabor Bergmann - * @since 2.1 - */ -public class SimpleLocalStorageBackend implements IStorageBackend { - - @Override - public void startTransaction() { - // NOP - } - - @Override - public void finishTransaction() { - // NOP - } - - @Override - public SimpleUnaryTable createUnaryTable(IInputKey key, ITableContext tableContext, boolean unique) { - return new SimpleUnaryTable<>(key, tableContext, unique); - } - - @Override - public SimpleBinaryTable createBinaryTable(IInputKey key, ITableContext tableContext, - boolean unique) { - return new SimpleBinaryTable<>(key, tableContext, unique); - } - - - -} diff --git a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/SimpleRuntimeContext.java b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/SimpleRuntimeContext.java deleted file mode 100644 index a3a827dc..00000000 --- a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/SimpleRuntimeContext.java +++ /dev/null @@ -1,132 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.matchers.scopes; - -import java.lang.reflect.InvocationTargetException; -import java.util.concurrent.Callable; - -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext; -import tools.refinery.viatra.runtime.matchers.context.IndexingService; -import tools.refinery.viatra.runtime.matchers.context.common.JavaTransitiveInstancesKey; -import tools.refinery.viatra.runtime.matchers.scopes.tables.IIndexTable; -import tools.refinery.viatra.runtime.matchers.tuple.ITuple; -import tools.refinery.viatra.runtime.matchers.tuple.Tuple; - -/** - * A simple demo implementation of the IQRC interface using tables. - * - *

- * Usage: first, instantiate {@link IIndexTable} tables with this as the 'tableContext' argument, and call - * {@link #registerIndexTable(IIndexTable)} manually to register them. Afterwards, they will be visible to the query - * backends. - *

- * EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will - * work or that it will remain the same. - * - * @author Gabor Bergmann - * @since 2.0 - */ -public class SimpleRuntimeContext extends TabularRuntimeContext { - - private IQueryMetaContext metaContext; - - public SimpleRuntimeContext(IQueryMetaContext metaContext) { - this.metaContext = metaContext; - } - - @Override - public void logError(String message) { - System.err.println(message); - } - - @Override - public IQueryMetaContext getMetaContext() { - return metaContext; - } - - @Override - public V coalesceTraversals(Callable callable) throws InvocationTargetException { - try { - return callable.call(); - } catch (Exception e) { - throw new InvocationTargetException(e); - } - } - - @Override - public boolean isCoalescing() { - return false; - } - - @Override - public boolean isIndexed(IInputKey key, IndexingService service) { - return peekIndexTable(key) != null; - } - - @Override - public void ensureIndexed(IInputKey key, IndexingService service) { - if (peekIndexTable(key) == null) - throw new IllegalArgumentException(key.getPrettyPrintableName()); - } - - @Override - public Object wrapElement(Object externalElement) { - return externalElement; - } - - @Override - public Object unwrapElement(Object internalElement) { - return internalElement; - } - - @Override - public Tuple wrapTuple(Tuple externalElements) { - return externalElements; - } - - @Override - public Tuple unwrapTuple(Tuple internalElements) { - return internalElements; - } - - @Override - public void ensureWildcardIndexing(IndexingService service) { - throw new UnsupportedOperationException(); - } - - @Override - public void executeAfterTraversal(Runnable runnable) throws InvocationTargetException { - runnable.run(); - } - - @Override - protected boolean isContainedInStatelessKey(IInputKey key, ITuple seed) { - if (key instanceof JavaTransitiveInstancesKey) { - Class instanceClass = forceGetWrapperInstanceClass((JavaTransitiveInstancesKey) key); - return instanceClass != null && instanceClass.isInstance(seed.get(0)); - } else - throw new IllegalArgumentException(key.getPrettyPrintableName()); - } - - private Class forceGetWrapperInstanceClass(JavaTransitiveInstancesKey key) { - Class instanceClass; - try { - instanceClass = key.forceGetWrapperInstanceClass(); - } catch (ClassNotFoundException e) { - logError( - "Could not load instance class for type constraint " + key.getWrappedKey() + ": " + e.getMessage()); - instanceClass = null; - } - return instanceClass; - } - -} diff --git a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/TabularRuntimeContext.java b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/TabularRuntimeContext.java deleted file mode 100644 index e99e24d3..00000000 --- a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/TabularRuntimeContext.java +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.matchers.scopes; - -import java.util.Map; -import java.util.Optional; - -import tools.refinery.viatra.runtime.matchers.context.AbstractQueryRuntimeContext; -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContextListener; -import tools.refinery.viatra.runtime.matchers.scopes.tables.IIndexTable; -import tools.refinery.viatra.runtime.matchers.scopes.tables.ITableContext; -import tools.refinery.viatra.runtime.matchers.tuple.ITuple; -import tools.refinery.viatra.runtime.matchers.tuple.Tuple; -import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; -import tools.refinery.viatra.runtime.matchers.util.Accuracy; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory; - -/** - * An abstract runtime context that serves enumerable input key instances from tables. - * - *

- * Usage: first, instantiate {@link IIndexTable} tables with this as the 'tableContext' argument. Call - * {@link #registerIndexTable(IIndexTable)} to register them; this may happen either during a coalesced indexing, or on - * external initiation. Afterwards, they will be visible to the query backends. - *

- * EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will - * work or that it will remain the same. - * - * @author Gabor Bergmann - * @since 2.0 - */ -public abstract class TabularRuntimeContext extends AbstractQueryRuntimeContext implements ITableContext { - - private Map instanceTables = CollectionsFactory.createMap(); - - public void registerIndexTable(IIndexTable table) { - IInputKey inputKey = table.getInputKey(); - instanceTables.put(inputKey, table); - } - - /** - * @return null if the table is not registered - */ - public IIndexTable peekIndexTable(IInputKey key) { - return instanceTables.get(key); - } - - /** - * If the table is not registered, {@link #handleUnregisteredTableRequest(IInputKey)} is invoked; it may handle it - * by raising an error or e.g. on-demand index construction - */ - public IIndexTable getIndexTable(IInputKey key) { - IIndexTable table = instanceTables.get(key); - if (table != null) - return table; - else - return handleUnregisteredTableRequest(key); - } - - /** - * Override this to provide on-demand table registration - */ - protected IIndexTable handleUnregisteredTableRequest(IInputKey key) { - throw new IllegalArgumentException(key.getPrettyPrintableName()); - } - - @Override - public int countTuples(IInputKey key, TupleMask seedMask, ITuple seed) { - return getIndexTable(key).countTuples(seedMask, seed); - } - - @Override - public Optional estimateCardinality(IInputKey key, TupleMask groupMask, Accuracy requiredAccuracy) { - return getIndexTable(key).estimateProjectionSize(groupMask, requiredAccuracy); - } - - @Override - public Iterable enumerateTuples(IInputKey key, TupleMask seedMask, ITuple seed) { - return getIndexTable(key).enumerateTuples(seedMask, seed); - } - - @Override - public Iterable enumerateValues(IInputKey key, TupleMask seedMask, ITuple seed) { - return getIndexTable(key).enumerateValues(seedMask, seed); - } - - @Override - public boolean containsTuple(IInputKey key, ITuple seed) { - if (key.isEnumerable()) { - return getIndexTable(key).containsTuple(seed); - } else { - return isContainedInStatelessKey(key, seed); - } - } - - @Override - public void addUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) { - getIndexTable(key).addUpdateListener(seed, listener); - } - @Override - public void removeUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) { - getIndexTable(key).removeUpdateListener(seed, listener); - } - - /** - * Handles non-enumerable input keys that are not backed by a table - */ - protected abstract boolean isContainedInStatelessKey(IInputKey key, ITuple seed); - -} diff --git a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/AbstractIndexTable.java b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/AbstractIndexTable.java deleted file mode 100644 index 7b557c33..00000000 --- a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/AbstractIndexTable.java +++ /dev/null @@ -1,266 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.matchers.scopes.tables; - -import java.util.List; - -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContextListener; -import tools.refinery.viatra.runtime.matchers.tuple.Tuple; -import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; -import tools.refinery.viatra.runtime.matchers.tuple.Tuples; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory.MemoryType; -import tools.refinery.viatra.runtime.matchers.util.IMultiLookup; - -/** - *

- * EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will - * work or that it will remain the same. - * - * @since 2.0 - * @author Gabor Bergmann - */ -public abstract class AbstractIndexTable implements IIndexTable { - - private IInputKey inputKey; - protected ITableContext tableContext; - - protected final TupleMask emptyMask; - protected final Tuple emptyTuple; - - - public AbstractIndexTable(IInputKey inputKey, ITableContext tableContext) { - this.inputKey = inputKey; - this.tableContext = tableContext; - - this.emptyMask = TupleMask.empty(getInputKey().getArity()); - this.emptyTuple = Tuples.flatTupleOf(new Object[inputKey.getArity()]); - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + ":" + inputKey.getPrettyPrintableName(); - } - - @Override - public IInputKey getInputKey() { - return inputKey; - } - - protected void logError(String message) { - tableContext.logError(message); - } - - - /// UPDATE HANDLING SECTION - - // The entire mechanism is designed to accommodate a large number of update listeners, - // but maybe there will typically be only a single, universal (unseeded) listener? - // TODO Create special handling for that case. - - // Invariant: true iff #listenerGroupsAndSeed is nonempty - protected boolean emitNotifications = false; - // Subscribed listeners grouped by their seed mask (e.g. all those that seed columns 2 and 5 are together), - // groups are stored in a list for quick delivery-time iteration (at the expense of adding / removing); - // individual listeners can be looked up based on their seed tuple - protected List listenerGroups = CollectionsFactory.createObserverList(); - - - /** - * Implementors shall call this to deliver all notifications. - * Call may be conditioned to {@link #emitNotifications} - */ - protected void deliverChangeNotifications(Tuple updateTuple, boolean isInsertion) { - for (IListenersWithSameMask listenersForSeed : listenerGroups) { - listenersForSeed.deliver(updateTuple, isInsertion); - } - } - - @Override - public void addUpdateListener(Tuple seed, IQueryRuntimeContextListener listener) { - TupleMask seedMask; - if (seed == null) { - seed = emptyTuple; - seedMask = emptyMask; - } else { - seedMask = TupleMask.fromNonNullIndices(seed); - } - IListenersWithSameMask listenerGroup = getListenerGroup(seedMask); - if (listenerGroup == null) { // create new group - switch (seedMask.getSize()) { - case 0: - listenerGroup = new UniversalListeners(); - break; - case 1: - listenerGroup = new ColumnBoundListeners(seedMask.indices[0]); - break; - default: - listenerGroup = new GenericBoundListeners(seedMask); - } - listenerGroups.add(listenerGroup); - emitNotifications = true; - } - listenerGroup.addUpdateListener(seed, listener); - } - - @Override - public void removeUpdateListener(Tuple seed, IQueryRuntimeContextListener listener) { - TupleMask seedMask; - if (seed == null) { - seed = emptyTuple; - seedMask = emptyMask; - } else { - seedMask = TupleMask.fromNonNullIndices(seed); - } - IListenersWithSameMask listenerGroup = getListenerGroup(seedMask); - if (listenerGroup == null) - throw new IllegalStateException("no listener subscribed with mask" + seedMask); - - if (listenerGroup.removeUpdateListener(seed, listener)) { - listenerGroups.remove(listenerGroup); - emitNotifications = !listenerGroups.isEmpty(); - } - } - - protected IListenersWithSameMask getListenerGroup(TupleMask seedMask) { - for (IListenersWithSameMask candidateGroup : listenerGroups) { // group already exists? - if (seedMask.equals(candidateGroup.getSeedMask())) { - return candidateGroup; - } - } - return null; - } - - - /** - * Represents all listeners subscribed to seeds with the given seed mask. - * - * @author Bergmann Gabor - */ - protected static interface IListenersWithSameMask { - - public TupleMask getSeedMask(); - - public void deliver(Tuple updateTuple, boolean isInsertion); - - public void addUpdateListener(Tuple originalSeed, IQueryRuntimeContextListener listener); - /** - * @return true if this was the last listener, and the {@link IListenersWithSameMask} can be disposed of. - */ - public boolean removeUpdateListener(Tuple originalSeed, IQueryRuntimeContextListener listener); - } - /** - * Listeners interested in all tuples - */ - protected final class UniversalListeners implements IListenersWithSameMask { - private final TupleMask mask = TupleMask.empty(inputKey.getArity()); - private List listeners = CollectionsFactory.createObserverList(); - - @Override - public TupleMask getSeedMask() { - return mask; - } - @Override - public void deliver(Tuple updateTuple, boolean isInsertion) { - IInputKey key = inputKey; - for (IQueryRuntimeContextListener listener : listeners) { - listener.update(key, updateTuple, isInsertion); - } - } - @Override - public void addUpdateListener(Tuple originalSeed, IQueryRuntimeContextListener listener) { - listeners.add(listener); - } - @Override - public boolean removeUpdateListener(Tuple originalSeed, IQueryRuntimeContextListener listener) { - listeners.remove(listener); - return listeners.isEmpty(); - } - } - /** - * Listeners interested in all tuples seeded by a single columns - */ - protected final class ColumnBoundListeners implements IListenersWithSameMask { - private int seedPosition; - protected final TupleMask mask; - // indexed by projected seed tuple - protected IMultiLookup listeners = - CollectionsFactory.createMultiLookup(Object.class, MemoryType.SETS, Object.class); - - public ColumnBoundListeners(int seedPosition) { - this.seedPosition = seedPosition; - this.mask = TupleMask.selectSingle(seedPosition, inputKey.getArity()); - } - - @Override - public TupleMask getSeedMask() { - return mask; - } - @Override - public void deliver(Tuple updateTuple, boolean isInsertion) { - IInputKey key = inputKey; - Object projectedSeed = updateTuple.get(seedPosition); - for (IQueryRuntimeContextListener listener : listeners.lookupOrEmpty(projectedSeed)) { - listener.update(key, updateTuple, isInsertion); - } - } - @Override - public void addUpdateListener(Tuple originalSeed, IQueryRuntimeContextListener listener) { - Object projectedSeed = originalSeed.get(seedPosition); - listeners.addPair(projectedSeed, listener); - } - @Override - public boolean removeUpdateListener(Tuple originalSeed, IQueryRuntimeContextListener listener) { - Object projectedSeed = originalSeed.get(seedPosition); - listeners.removePair(projectedSeed, listener); - return listeners.countKeys() == 0; - } - } - /** - * Listeners interested in all tuples seeded by a tuple of values - */ - protected final class GenericBoundListeners implements IListenersWithSameMask { - protected final TupleMask mask; - // indexed by projected seed tuple - protected IMultiLookup listeners = - CollectionsFactory.createMultiLookup(Object.class, MemoryType.SETS, Object.class); - - public GenericBoundListeners(TupleMask mask) { - this.mask = mask; - } - - @Override - public TupleMask getSeedMask() { - return mask; - } - @Override - public void deliver(Tuple updateTuple, boolean isInsertion) { - IInputKey key = inputKey; - Tuple projectedSeed = mask.transform(updateTuple); - for (IQueryRuntimeContextListener listener : listeners.lookupOrEmpty(projectedSeed)) { - listener.update(key, updateTuple, isInsertion); - } - } - @Override - public void addUpdateListener(Tuple originalSeed, IQueryRuntimeContextListener listener) { - Tuple projectedSeed = mask.transform(originalSeed); - listeners.addPair(projectedSeed, listener); - } - @Override - public boolean removeUpdateListener(Tuple originalSeed, IQueryRuntimeContextListener listener) { - Tuple projectedSeed = mask.transform(originalSeed); - listeners.removePair(projectedSeed, listener); - return listeners.countKeys() == 0; - } - } - - -} \ No newline at end of file diff --git a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/DefaultIndexTable.java b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/DefaultIndexTable.java deleted file mode 100644 index 39475d11..00000000 --- a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/DefaultIndexTable.java +++ /dev/null @@ -1,143 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.matchers.scopes.tables; - -import java.util.Map; -import java.util.Optional; -import java.util.stream.Stream; - -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.memories.MaskedTupleMemory; -import tools.refinery.viatra.runtime.matchers.tuple.ITuple; -import tools.refinery.viatra.runtime.matchers.tuple.Tuple; -import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; -import tools.refinery.viatra.runtime.matchers.util.Accuracy; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory.MemoryType; -import tools.refinery.viatra.runtime.matchers.util.Direction; -import tools.refinery.viatra.runtime.matchers.util.IMemory; - -/** - * Demo default implementation. - *

- * EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will - * work or that it will remain the same. - * - * @since 2.0 - * @author Gabor Bergmann - */ -public class DefaultIndexTable extends AbstractIndexTable implements ITableWriterGeneric { - - protected IMemory rows = CollectionsFactory.createMultiset(); // TODO use SetMemory if unique - protected Map> indexMemories = CollectionsFactory.createMap(); - private boolean unique; - - /** - * @param unique - * client promises to only insert a given tuple with multiplicity one - */ - public DefaultIndexTable(IInputKey inputKey, ITableContext tableContext, boolean unique) { - super(inputKey, tableContext); - this.unique = unique; - } - - @Override - public void write(Direction direction, Tuple row) { - if (direction == Direction.INSERT) { - boolean changed = rows.addOne(row); - if (unique && !changed) { - String msg = String.format( - "Error: trying to add duplicate row %s to the unique table %s. This indicates some errors in underlying model representation.", - row, getInputKey().getPrettyPrintableName()); - logError(msg); - } - if (changed) { - for (MaskedTupleMemory indexMemory : indexMemories.values()) { - indexMemory.add(row); - } - if (emitNotifications) { - deliverChangeNotifications(row, true); - } - } - } else { // DELETE - boolean changed = rows.removeOne(row); - if (unique && !changed) { - String msg = String.format( - "Error: trying to remove duplicate value %s from the unique table %s. This indicates some errors in underlying model representation.", - row, getInputKey().getPrettyPrintableName()); - logError(msg); - } - if (changed) { - for (MaskedTupleMemory indexMemory : indexMemories.values()) { - indexMemory.remove(row); - } - if (emitNotifications) { - deliverChangeNotifications(row, false); - } - } - } - } - - @Override - public boolean containsTuple(ITuple seed) { - return rows.distinctValues().contains(seed); - } - - private MaskedTupleMemory getIndexMemory(TupleMask seedMask) { - return indexMemories.computeIfAbsent(seedMask, mask -> { - MaskedTupleMemory memory = MaskedTupleMemory.create(seedMask, MemoryType.SETS, DefaultIndexTable.this); - for (Tuple tuple : rows.distinctValues()) { - memory.add(tuple); - } - return memory; - }); - } - - @Override - public int countTuples(TupleMask seedMask, ITuple seed) { - switch (seedMask.getSize()) { - case 0: // unseeded - return rows.size(); - default: - return getIndexMemory(seedMask).getOrEmpty(seed).size(); - } - } - - @Override - public Optional estimateProjectionSize(TupleMask groupMask, Accuracy requiredAccuracy) { - // always exact count - if (groupMask.getSize() == 0) { - return rows.size() == 0 ? Optional.of(0L) : Optional.of(1L); - } else if (groupMask.getSize() == this.emptyTuple.getSize()) { - return Optional.of((long) rows.size()); - } else { - return Optional.of((long)getIndexMemory(groupMask).getKeysetSize()); - } - } - - @Override - public Iterable enumerateTuples(TupleMask seedMask, ITuple seed) { - return getIndexMemory(seedMask).getOrEmpty(seed); - } - - @Override - public Stream streamTuples(TupleMask seedMask, ITuple seed) { - return getIndexMemory(seedMask).getOrEmpty(seed).stream(); - } - - @Override - public Stream streamValues(TupleMask seedMask, ITuple seed) { - // we assume there is a single omitted index in the mask - int queriedColumn = seedMask.getFirstOmittedIndex().getAsInt(); - return getIndexMemory(seedMask).getOrEmpty(seed).stream() - .map(row2 -> row2.get(queriedColumn)); - } - -} diff --git a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/DisjointUnionTable.java b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/DisjointUnionTable.java deleted file mode 100644 index a3a65f14..00000000 --- a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/DisjointUnionTable.java +++ /dev/null @@ -1,192 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.matchers.scopes.tables; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Stream; - -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContextListener; -import tools.refinery.viatra.runtime.matchers.tuple.ITuple; -import tools.refinery.viatra.runtime.matchers.tuple.Tuple; -import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; -import tools.refinery.viatra.runtime.matchers.tuple.Tuples; -import tools.refinery.viatra.runtime.matchers.util.Accuracy; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory; - -/** - * Disjoint union of the provided child tables. - * - * Used e.g. to present a transitive instance table as a view composed from direct instance tables. - *

- * EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will - * work or that it will remain the same. - * - * @since 2.0 - * @author Gabor Bergmann - */ -public class DisjointUnionTable extends AbstractIndexTable { - - protected List childTables = CollectionsFactory.createObserverList(); - - public DisjointUnionTable(IInputKey inputKey, ITableContext tableContext) { - super(inputKey, tableContext); - } - - public List getChildTables() { - return Collections.unmodifiableList(childTables); - } - - /** - * Precondition: the new child currently is, and will forever stay, disjoint from any other child tables. - */ - public void addChildTable(IIndexTable child) { - if (getInputKey().getArity() != child.getInputKey().getArity()) - throw new IllegalArgumentException(child.toString()); - - childTables.add(child); - - if (emitNotifications) { - for (Tuple tuple : child.enumerateTuples(emptyMask, Tuples.staticArityFlatTupleOf())) { - deliverChangeNotifications(tuple, true); - } - } - } - - @Override - public int countTuples(TupleMask seedMask, ITuple seed) { - int count = 0; - for (IIndexTable child : childTables) { - count += child.countTuples(seedMask, seed); - } - return count; - } - - - @Override - public Optional estimateProjectionSize(TupleMask groupMask, Accuracy requiredAccuracy) { - // exact results for trivial projections - if (groupMask.getSize() == 0) { - for (IIndexTable child : childTables) { - if (0 != child.countTuples(this.emptyMask, Tuples.staticArityFlatTupleOf())) - return Optional.of(1L); - } - return Optional.of(0L); - } else if (groupMask.getSize() == emptyTuple.getSize()) { - return Optional.of((long)countTuples(this.emptyMask, Tuples.staticArityFlatTupleOf())); - } - // summing child tables is an upper bound - if (Accuracy.BEST_UPPER_BOUND.atLeastAsPreciseAs(requiredAccuracy)) { - return Optional.of((long)countTuples(this.emptyMask, Tuples.staticArityFlatTupleOf())); - } else { // (Accuracy.BEST_LOWER_BOUND == requiredAccuracy) - //projections of child tables may coincide, but the largest one is still a lower bound - Optional maxProjection = Optional.empty(); - for (IIndexTable child : childTables) { - Optional estimateOfChild = child.estimateProjectionSize(groupMask, requiredAccuracy); - if (estimateOfChild.isPresent()) { - maxProjection = Optional.of(Math.max(estimateOfChild.get(), maxProjection.orElse(0L))); - } - } - return maxProjection; - } - } - - @Override - public Stream streamTuples(TupleMask seedMask, ITuple seed) { - Stream stream = Stream.empty(); - for (IIndexTable child : childTables) { - Stream childStream = child.streamTuples(seedMask, seed); - stream = Stream.concat(stream, childStream); - } - return stream; - } - - @Override - public Stream streamValues(TupleMask seedMask, ITuple seed) { - Stream stream = Stream.empty(); - for (IIndexTable child : childTables) { - Stream childStream = child.streamValues(seedMask, seed); - stream = Stream.concat(stream, childStream); - } - return stream; - } - - @Override - public boolean containsTuple(ITuple seed) { - for (IIndexTable child : childTables) { - if (child.containsTuple(seed)) - return true; - } - return false; - } - - @Override - public void addUpdateListener(Tuple seed, IQueryRuntimeContextListener listener) { - super.addUpdateListener(seed, listener); - - for (IIndexTable table : childTables) { - table.addUpdateListener(seed, new ListenerWrapper(listener)); - } - } - @Override - public void removeUpdateListener(Tuple seed, IQueryRuntimeContextListener listener) { - super.removeUpdateListener(seed, listener); - - for (IIndexTable table : childTables) { - table.removeUpdateListener(seed, new ListenerWrapper(listener)); - } - } - - - // TODO this would not be necessary - // if we moved from IQRCL to an interface that does not expose the input key - private class ListenerWrapper implements IQueryRuntimeContextListener { - - private IQueryRuntimeContextListener wrappedListener; - public ListenerWrapper(IQueryRuntimeContextListener wrappedListener) { - this.wrappedListener = wrappedListener; - } - - @Override - public void update(IInputKey key, Tuple updateTuple, boolean isInsertion) { - wrappedListener.update(getInputKey(), updateTuple, isInsertion); - } - - @Override - public int hashCode() { - return Objects.hash(wrappedListener, DisjointUnionTable.this); - } - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ListenerWrapper other = (ListenerWrapper) obj; - if (!getOuterType().equals(other.getOuterType())) - return false; - return Objects.equals(wrappedListener, other.wrappedListener); - } - private DisjointUnionTable getOuterType() { - return DisjointUnionTable.this; - } - @Override - public String toString() { - return "Wrapper to DisjointUnion("+getInputKey().getPrettyPrintableName()+") for " + wrappedListener; - } - } - -} diff --git a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/IIndexTable.java b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/IIndexTable.java deleted file mode 100644 index be375393..00000000 --- a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/IIndexTable.java +++ /dev/null @@ -1,212 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.matchers.scopes.tables; - -import java.util.Iterator; -import java.util.Optional; -import java.util.stream.Stream; - -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext; -import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContext; -import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContextListener; -import tools.refinery.viatra.runtime.matchers.tuple.ITuple; -import tools.refinery.viatra.runtime.matchers.tuple.Tuple; -import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; -import tools.refinery.viatra.runtime.matchers.util.Accuracy; - -/** - * Read-only interface that provides the {@link IInputKey}-specific slice of an instance store to realize a - * {@link IQueryRuntimeContext}. Implemented by a customizable data store that is responsible for: - *

    - *
  • storing the instance tuples of the {@link IInputKey},
  • - *
  • providing efficient lookup via storage-specific indexing,
  • - *
  • delivering notifications. (TODO not designed yet)
  • - *
- * - *

- * Can be specialized for unary / binary / etc., opposite edges or node subtypes, specific types, distributed storage, - * etc. - *

- * Writeable API is specific to the customized implementations (e.g. unary). - * - *

- * Precondition: the associated input key is enumerable, see {@link IQueryMetaContext#isEnumerable(IInputKey)}. - *

- * EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will - * work or that it will remain the same. - * - * @since 2.0 - * @author Gabor Bergmann - * @noimplement This interface is not intended to be implemented directly. Extend {@link AbstractIndexTable} instead. - */ -public interface IIndexTable { - - // TODO add superinterface that represents a statistics-only counter? - - /** - * @return the input key indexed by this table - */ - public IInputKey getInputKey(); - - /** - * Returns the tuples, optionally seeded with the given tuple. - * - *

Consider using the more idiomatic {@link #streamTuples(TupleMask, ITuple)} instead. - * - * @param seedMask - * a mask that extracts those parameters of the input key (from the entire parameter list) that should be - * bound to a fixed value; must not be null. Note: any given index must occur at most - * once in seedMask. - * @param seed - * the tuple of fixed values restricting the row set to be considered, in the same order as given in - * parameterSeedMask, so that for each considered row tuple, - * projectedParameterSeed.equals(parameterSeedMask.transform(row)) should hold. Must not be null. - * @return the tuples in the table for the given key and seed - */ - @SuppressWarnings("unchecked") - public default Iterable enumerateTuples(TupleMask seedMask, ITuple seed) { - return () -> (Iterator) (streamTuples(seedMask, seed).iterator()); - } - - /** - * Returns the tuples, optionally seeded with the given tuple. - * - * @param seedMask - * a mask that extracts those parameters of the input key (from the entire parameter list) that should be - * bound to a fixed value; must not be null. Note: any given index must occur at most - * once in seedMask. - * @param seed - * the tuple of fixed values restricting the row set to be considered, in the same order as given in - * parameterSeedMask, so that for each considered row tuple, - * projectedParameterSeed.equals(parameterSeedMask.transform(row)) should hold. Must not be null. - * @return the tuples in the table for the given key and seed - * @since 2.1 - */ - public Stream streamTuples(TupleMask seedMask, ITuple seed); - - /** - * Simpler form of {@link #enumerateTuples(TupleMask, ITuple)} in the case where all values of the tuples are bound - * by the seed except for one. - * - *

- * Selects the tuples in the table, optionally seeded with the given tuple, and then returns the single value from - * each tuple which is not bound by the seed mask. - * - *

Consider using the more idiomatic {@link #streamValues(TupleMask, ITuple)} instead. - * - * @param seedMask - * a mask that extracts those parameters of the input key (from the entire parameter list) that should be - * bound to a fixed value; must not be null. Note: any given index must occur at most - * once in seedMask, and seedMask must include all parameters in any arbitrary order except one. - * @param seed - * the tuple of fixed values restricting the row set to be considered, in the same order as given in - * parameterSeedMask, so that for each considered row tuple, - * projectedParameterSeed.equals(parameterSeedMask.transform(row)) should hold. Must not be null. - * @return the objects in the table for the given key and seed - * - */ - @SuppressWarnings("unchecked") - public default Iterable enumerateValues(TupleMask seedMask, ITuple seed) { - return () -> (Iterator) (streamValues(seedMask, seed).iterator()); - } - - /** - * Simpler form of {@link #enumerateTuples(TupleMask, ITuple)} in the case where all values of the tuples are bound - * by the seed except for one. - * - *

- * Selects the tuples in the table, optionally seeded with the given tuple, and then returns the single value from - * each tuple which is not bound by the seed mask. - * - * @param seedMask - * a mask that extracts those parameters of the input key (from the entire parameter list) that should be - * bound to a fixed value; must not be null. Note: any given index must occur at most - * once in seedMask, and seedMask must include all parameters in any arbitrary order except one. - * @param seed - * the tuple of fixed values restricting the row set to be considered, in the same order as given in - * parameterSeedMask, so that for each considered row tuple, - * projectedParameterSeed.equals(parameterSeedMask.transform(row)) should hold. Must not be null. - * @return the objects in the table for the given key and seed - * - * @since 2.1 - */ - public Stream streamValues(TupleMask seedMask, ITuple seed); - - /** - * Simpler form of {@link #enumerateTuples(TupleMask, ITuple)} in the case where all values of the tuples are bound - * by the seed. - * - *

- * Returns whether the given tuple is in the table identified by the input key. - * - * @param seed - * a row tuple of fixed values whose presence in the table is queried - * @return true iff there is a row tuple contained in the table that corresponds to the given seed - */ - public boolean containsTuple(ITuple seed); - - /** - * Returns the number of tuples, optionally seeded with the given tuple. - * - *

- * Selects the tuples in the table, optionally seeded with the given tuple, and then returns their number. - * - * @param seedMask - * a mask that extracts those parameters of the input key (from the entire parameter list) that should be - * bound to a fixed value; must not be null. Note: any given index must occur at most - * once in seedMask. - * @param seed - * the tuple of fixed values restricting the row set to be considered, in the same order as given in - * parameterSeedMask, so that for each considered row tuple, - * projectedParameterSeed.equals(parameterSeedMask.transform(row)) should hold. Must not be null. - * @return the number of tuples in the table for the given key and seed - * - */ - public int countTuples(TupleMask seedMask, ITuple seed); - - /** - * Gives an estimate of the number of different groups the tuples of the table are projected into by the given mask - * (e.g. for an identity mask, this means the full relation size). The estimate must meet the required accuracy. - * - *

Derived tables may return {@link Optional#empty()} if it would be costly to provide an answer up to the required precision. - * Direct storage tables are expected to always be able to give an exact count. - * - *

PRE: {@link TupleMask#isNonrepeating()} must hold for the group mask. - * - * @since 2.1 - */ - public Optional estimateProjectionSize(TupleMask groupMask, Accuracy requiredAccuracy); - - /** - * Subscribes for updates in the table, optionally seeded with the given tuple. - *

This should be called after initializing a result cache by an enumeration method. - * - * @param seed can be null or a tuple with matching arity; - * if non-null, notifications will delivered only about those updates of the table - * that match the seed at positions where the seed is non-null. - * @param listener will be notified of future changes - * - * @since 2.1 - */ - public void addUpdateListener(Tuple seed, IQueryRuntimeContextListener listener); - - /** - * Unsubscribes from updates in the table, optionally seeded with the given tuple. - * - * @param seed can be null or a tuple with matching arity; - * see {@link #addUpdateListener(Tuple, IQueryRuntimeContextListener)} for definition. - * @param listener will no longer be notified of future changes - * - * @since 2.1 - */ - public void removeUpdateListener(Tuple seed, IQueryRuntimeContextListener listener); - -} diff --git a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/ITableContext.java b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/ITableContext.java deleted file mode 100644 index 69e83cd7..00000000 --- a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/ITableContext.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.matchers.scopes.tables; - -/** - * Callbacks that {@link IIndexTable} implementations are expected to invoke on their environment. - *

- * EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will - * work or that it will remain the same. - * - * @since 2.0 - * @author Gabor Bergmann - */ -public interface ITableContext { - - // TODO notifications? - - /** - * Indicates that an error has occurred in maintaining an index table, e.g. duplicate value. - */ - public void logError(String message); -} diff --git a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/ITableWriterBinary.java b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/ITableWriterBinary.java deleted file mode 100644 index fb614014..00000000 --- a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/ITableWriterBinary.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.matchers.scopes.tables; - -import tools.refinery.viatra.runtime.matchers.util.Direction; - -/** - * Modifies the contents of a binary {@link IIndexTable}. - *

- * EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will - * work or that it will remain the same. - * - * @since 2.0 - * @author Gabor Bergmann - */ -public interface ITableWriterBinary { - /** - * Adds/removes a row to/from the table. - * - * @param direction - * tells whether putting a row into the table or deleting - * - * TODO: store as multiset, return bool? - */ - void write(Direction direction, Source source, Target target); - - /** - * Intersection type for writers that are also tables - */ - interface Table extends ITableWriterBinary, IIndexTable { - } - - /** - * /dev/null implementation - * - * @author Gabor Bergmann - */ - static class Nop implements ITableWriterBinary { - @Override - public void write(Direction direction, Source source, Target target) { - // NO-OP - } - - } -} diff --git a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/ITableWriterGeneric.java b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/ITableWriterGeneric.java deleted file mode 100644 index fb1ebcc0..00000000 --- a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/ITableWriterGeneric.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.matchers.scopes.tables; - -import tools.refinery.viatra.runtime.matchers.tuple.Tuple; -import tools.refinery.viatra.runtime.matchers.util.Direction; - -/** - * Modifies the contents of an {@link IIndexTable}. - *

- * EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will - * work or that it will remain the same. - * - * @since 2.0 - * @author Gabor Bergmann - */ -public interface ITableWriterGeneric { - - /** - * Adds/removes a row to/from the table. - * - * @param direction - * tells whether putting a row into the table or deleting TODO: store as multiset, return bool? - */ - void write(Direction direction, Tuple row); - - /** - * Intersection type for writers that are also tables - */ - interface Table extends ITableWriterGeneric, IIndexTable { - } - - /** - * /dev/null implementation - * - * @author Gabor Bergmann - */ - static class Nop implements ITableWriterGeneric { - @Override - public void write(Direction direction, Tuple row) { - // NO-OP - } - - } -} diff --git a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/ITableWriterUnary.java b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/ITableWriterUnary.java deleted file mode 100644 index f90d5362..00000000 --- a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/ITableWriterUnary.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.matchers.scopes.tables; - -import tools.refinery.viatra.runtime.matchers.util.Direction; - -/** - * Modifies the contents of a unary {@link IIndexTable}. - *

- * EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will - * work or that it will remain the same. - * - * @since 2.0 - * @author Gabor Bergmann - * - */ -public interface ITableWriterUnary { - - /** - * Adds/removes a row to/from the table. - * - * @param direction - * tells whether putting a row into the table or deleting TODO: store as multiset, return bool? - */ - void write(Direction direction, Value value); - - /** - * Intersection type for writers that are also tables - */ - interface Table extends ITableWriterUnary, IIndexTable { - } - - /** - * /dev/null implementation - * - * @author Gabor Bergmann - */ - static class Nop implements ITableWriterUnary { - @Override - public void write(Direction direction, Value value) { - // NO-OP - } - } -} diff --git a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/SimpleBinaryTable.java b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/SimpleBinaryTable.java deleted file mode 100644 index 588ed9d2..00000000 --- a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/SimpleBinaryTable.java +++ /dev/null @@ -1,320 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.matchers.scopes.tables; - -import java.util.Collections; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Stream; - -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.tuple.ITuple; -import tools.refinery.viatra.runtime.matchers.tuple.Tuple; -import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; -import tools.refinery.viatra.runtime.matchers.tuple.Tuples; -import tools.refinery.viatra.runtime.matchers.util.Accuracy; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory.MemoryType; -import tools.refinery.viatra.runtime.matchers.util.Direction; -import tools.refinery.viatra.runtime.matchers.util.IMemoryView; -import tools.refinery.viatra.runtime.matchers.util.IMultiLookup; -import tools.refinery.viatra.runtime.matchers.util.IMultiLookup.ChangeGranularity; - -/** - * Simple source-target bidirectional mapping. - * - *

- * TODO: specialize for to-one features and unique to-many features - *

- * TODO: on-demand construction of valueToHolderMap - *

- * TODO: support for lean indexing, opposites, long surrogate ids, etc. - *

- * EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will - * work or that it will remain the same. - * - * @since 2.0 - * @author Gabor Bergmann - */ -public class SimpleBinaryTable extends AbstractIndexTable - implements ITableWriterBinary.Table { - - /** - * value -> holder(s) - *

- * this is currently the primary store, may hold duplicates depending on the unique parameter - */ - private IMultiLookup valueToHolderMap; - /** - * holder -> value(s); constructed on-demand, null if unused - */ - private IMultiLookup holderToValueMap; - private int totalRowCount = 0; - private boolean unique; - - /** - * @param unique - * client promises to only insert a given tuple with multiplicity one - */ - public SimpleBinaryTable(IInputKey inputKey, ITableContext tableContext, boolean unique) { - super(inputKey, tableContext); - this.unique = unique; - valueToHolderMap = CollectionsFactory.createMultiLookup(Object.class, - unique ? MemoryType.SETS : MemoryType.MULTISETS, Object.class); - if (2 != inputKey.getArity()) - throw new IllegalArgumentException(inputKey.toString()); - } - - @Override - public void write(Direction direction, Source holder, Target value) { - if (direction == Direction.INSERT) { - try { - // TODO we currently assume V2H map exists - boolean changed = addToValueToHolderMap(value, holder); - if (holderToValueMap != null) { - addToHolderToValueMap(value, holder); - } - if (changed) { - totalRowCount++; - if (emitNotifications) { - deliverChangeNotifications(Tuples.staticArityFlatTupleOf(holder, value), true); - } - } - } catch (IllegalStateException ex) { // if unique table and duplicate tuple - String msg = String.format( - "Error: trying to add duplicate value %s to the unique feature %s of host object %s. This indicates some errors in underlying model representation.", - value, getInputKey().getPrettyPrintableName(), holder); - logError(msg); - } - } else { // DELETE - try { - // TODO we currently assume V2H map exists - boolean changed = removeFromValueToHolderMap(value, holder); - if (holderToValueMap != null) { - removeFromHolderToValueMap(value, holder); - } - if (changed) { - totalRowCount--; - if (emitNotifications) { - deliverChangeNotifications(Tuples.staticArityFlatTupleOf(holder, value), false); - } - } - } catch (IllegalStateException ex) { // if unique table and duplicate tuple - String msg = String.format( - "Error: trying to remove non-existing value %s from the feature %s of host object %s. This indicates some errors in underlying model representation.", - value, getInputKey().getPrettyPrintableName(), holder); - logError(msg); - } - } - } - - private boolean addToHolderToValueMap(Target value, Source holder) { - return ChangeGranularity.DUPLICATE != holderToValueMap.addPair(holder, value); - } - - private boolean addToValueToHolderMap(Target value, Source holder) { - return ChangeGranularity.DUPLICATE != valueToHolderMap.addPair(value, holder); - } - - /** - * @throws IllegalStateException - */ - private boolean removeFromHolderToValueMap(Target value, Source holder) { - return ChangeGranularity.DUPLICATE != holderToValueMap.removePair(holder, value); - } - - /** - * @throws IllegalStateException - */ - private boolean removeFromValueToHolderMap(Target value, Source holder) { - return ChangeGranularity.DUPLICATE != valueToHolderMap.removePair(value, holder); - } - - @SuppressWarnings("unchecked") - @Override - public int countTuples(TupleMask seedMask, ITuple seed) { - switch (seedMask.getSize()) { - case 0: // unseeded - // TODO we currently assume V2H map exists - return totalRowCount; - case 1: // lookup by source or target - int seedIndex = seedMask.indices[0]; - if (seedIndex == 0) { // lookup by source - Source source = (Source) seed.get(0); - return getDistinctValuesOfHolder(source).size(); - } else if (seedIndex == 1) { // lookup by target - Target target = (Target) seed.get(0); - return getDistinctHoldersOfValue(target).size(); - } else - throw new IllegalArgumentException(seedMask.toString()); - case 2: // containment check - // hack: if mask is not identity, then it is [1,0]/2, which is its own inverse - Source source = (Source) seedMask.getValue(seed, 0); - Target target = (Target) seedMask.getValue(seed, 1); - if (containsRow(source, target)) - return 1; - else - return 0; - default: - throw new IllegalArgumentException(seedMask.toString()); - } - } - - @Override - public Optional estimateProjectionSize(TupleMask groupMask, Accuracy requiredAccuracy) { - // always exact count - if (groupMask.getSize() == 0) { - return totalRowCount == 0 ? Optional.of(0L) : Optional.of(1L); - } else if (groupMask.getSize() == 2) { - return Optional.of((long)totalRowCount); - } else if (groupMask.indices[0] == 0) { // project to holder - return Optional.of((long)getHolderToValueMap().countKeys()); - } else { // (groupMask.indices[0] == 0) // project to value - return Optional.of((long)getValueToHolderMap().countKeys()); - } - } - - @Override - public Stream streamTuples(TupleMask seedMask, ITuple seed) { - switch (seedMask.getSize()) { - case 0: // unseeded - // TODO we currently assume V2H map exists - return getAllDistinctValuesStream() - .flatMap(value -> valueToHolderMap.lookup(value).distinctValues().stream() - .map(source -> Tuples.staticArityFlatTupleOf(source, value))); - - case 1: // lookup by source or target - int seedIndex = seedMask.indices[0]; - if (seedIndex == 0) { // lookup by source - @SuppressWarnings("unchecked") - Source source = (Source) seed.get(0); - return getDistinctValuesOfHolder(source).stream() - .map(target -> Tuples.staticArityFlatTupleOf(source, target)); - } else if (seedIndex == 1) { // lookup by target - @SuppressWarnings("unchecked") - Target target = (Target) seed.get(0); - return getDistinctHoldersOfValue(target).stream() - .map(source -> Tuples.staticArityFlatTupleOf(source, target)); - } else - throw new IllegalArgumentException(seedMask.toString()); - case 2: // containment check - // hack: if mask is not identity, then it is [1,0]/2, which is its own inverse - @SuppressWarnings("unchecked") - Source source = (Source) seedMask.getValue(seed, 0); - @SuppressWarnings("unchecked") - Target target = (Target) seedMask.getValue(seed, 1); - - if (containsRow(source, target)) - return Stream.of(Tuples.staticArityFlatTupleOf(source, target)); - else - return Stream.empty(); - default: - throw new IllegalArgumentException(seedMask.toString()); - } - } - - @Override - @SuppressWarnings("unchecked") - public Iterable enumerateValues(TupleMask seedMask, ITuple seed) { - if (seedMask.getSize() != 1) - throw new IllegalArgumentException(seedMask.toString()); - - int seedIndex = seedMask.indices[0]; - if (seedIndex == 0) { // lookup by source - return getDistinctValuesOfHolder((Source) seed.get(0)); - } else if (seedIndex == 1) { // lookup by target - return getDistinctHoldersOfValue((Target) seed.get(0)); - } else - throw new IllegalArgumentException(seedMask.toString()); - - } - @Override - public Stream streamValues(TupleMask seedMask, ITuple seed) { - if (seedMask.getSize() != 1) - throw new IllegalArgumentException(seedMask.toString()); - - int seedIndex = seedMask.indices[0]; - if (seedIndex == 0) { // lookup by source - return getDistinctValuesOfHolder((Source) seed.get(0)).stream(); - } else if (seedIndex == 1) { // lookup by target - return getDistinctHoldersOfValue((Target) seed.get(0)).stream(); - } else - throw new IllegalArgumentException(seedMask.toString()); - - } - - @Override - @SuppressWarnings("unchecked") - public boolean containsTuple(ITuple seed) { - return containsRow((Source) seed.get(0), (Target) seed.get(1)); - } - - public boolean containsRow(Source source, Target target) { - // TODO we currently assume V2H map exists - if (valueToHolderMap != null) { - IMemoryView holders = valueToHolderMap.lookup(target); - return holders != null && holders.containsNonZero(source); - } else - throw new UnsupportedOperationException("TODO implement"); - } - - public Iterable getAllDistinctHolders() { - return getHolderToValueMap().distinctKeys(); - } - public Stream getAllDistinctHoldersStream() { - return getHolderToValueMap().distinctKeysStream(); - } - public Iterable getAllDistinctValues() { - return getValueToHolderMap().distinctKeys(); - } - public Stream getAllDistinctValuesStream() { - return getValueToHolderMap().distinctKeysStream(); - } - - public Set getDistinctHoldersOfValue(Target value) { - IMemoryView holdersMultiset = getValueToHolderMap().lookup(value); - if (holdersMultiset == null) - return Collections.emptySet(); - else - return holdersMultiset.distinctValues(); - } - - public Set getDistinctValuesOfHolder(Source holder) { - IMemoryView valuesMultiset = getHolderToValueMap().lookup(holder); - if (valuesMultiset == null) - return Collections.emptySet(); - else - return valuesMultiset.distinctValues(); - } - - private IMultiLookup getHolderToValueMap() { - if (holderToValueMap == null) { - holderToValueMap = CollectionsFactory.createMultiLookup(Object.class, MemoryType.SETS, // no duplicates, as - // this is the - // secondary - // collection - Object.class); - - // TODO we currently assume V2H map exists - for (Target value : valueToHolderMap.distinctKeys()) { - for (Source holder : valueToHolderMap.lookup(value).distinctValues()) { - holderToValueMap.addPair(holder, value); - } - } - } - return holderToValueMap; - } - - private IMultiLookup getValueToHolderMap() { - // TODO we currently assume V2H map exists - return valueToHolderMap; - } - -} diff --git a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/SimpleUnaryTable.java b/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/SimpleUnaryTable.java deleted file mode 100644 index 428ea78b..00000000 --- a/subprojects/viatra-runtime-matchers/src/main/java/tools/refinery/viatra/runtime/matchers/scopes/tables/SimpleUnaryTable.java +++ /dev/null @@ -1,140 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.matchers.scopes.tables; - -import java.util.Optional; -import java.util.stream.Stream; - -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.tuple.ITuple; -import tools.refinery.viatra.runtime.matchers.tuple.Tuple; -import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; -import tools.refinery.viatra.runtime.matchers.tuple.Tuples; -import tools.refinery.viatra.runtime.matchers.util.Accuracy; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory; -import tools.refinery.viatra.runtime.matchers.util.Direction; -import tools.refinery.viatra.runtime.matchers.util.IMemory; - -/** - * Simple value set. - *

- * EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will - * work or that it will remain the same. - * - * @since 2.0 - * @author Gabor Bergmann - */ -public class SimpleUnaryTable extends AbstractIndexTable implements ITableWriterUnary.Table { - - protected IMemory values = CollectionsFactory.createMultiset(); // TODO use SetMemory if unique - - private boolean unique; - - /** - * @param unique - * client promises to only insert a given tuple with multiplicity one - */ - public SimpleUnaryTable(IInputKey inputKey, ITableContext tableContext, boolean unique) { - super(inputKey, tableContext); - this.unique = unique; - if (1 != inputKey.getArity()) - throw new IllegalArgumentException(inputKey.toString()); - } - - @Override - public void write(Direction direction, Value value) { - if (direction == Direction.INSERT) { - boolean changed = values.addOne(value); - if (unique && !changed) { - String msg = String.format( - "Error: trying to add duplicate value %s to the unique set %s. This indicates some errors in underlying model representation.", - value, getInputKey().getPrettyPrintableName()); - logError(msg); - } - if (changed && emitNotifications) { - deliverChangeNotifications(Tuples.staticArityFlatTupleOf(value), true); - } - } else { // DELETE - boolean changed = values.removeOne(value); - if (unique && !changed) { - String msg = String.format( - "Error: trying to remove duplicate value %s from the unique set %s. This indicates some errors in underlying model representation.", - value, getInputKey().getPrettyPrintableName()); - logError(msg); - } - if (changed && emitNotifications) { - deliverChangeNotifications(Tuples.staticArityFlatTupleOf(value), false); - } - } - } - - @Override - @SuppressWarnings("unchecked") - public boolean containsTuple(ITuple seed) { - return values.containsNonZero((Value) seed.get(0)); - } - - @Override - public int countTuples(TupleMask seedMask, ITuple seed) { - if (seedMask.getSize() == 0) { // unseeded - return values.size(); - } else { - @SuppressWarnings("unchecked") - Value value = (Value) seed.get(0); - return values.containsNonZero(value) ? 1 : 0; - } - } - - - @Override - public Optional estimateProjectionSize(TupleMask groupMask, Accuracy requiredAccuracy) { - // always exact count - if (groupMask.getSize() == 0) { - return values.isEmpty() ? Optional.of(0L) : Optional.of(1L); - } else { - return Optional.of((long)values.size()); - } - } - - - @Override - public Stream streamTuples(TupleMask seedMask, ITuple seed) { - if (seedMask.getSize() == 0) { // unseeded - return values.distinctValues().stream().map(Tuples::staticArityFlatTupleOf); - } else { - @SuppressWarnings("unchecked") - Value value = (Value) seed.get(0); - if (values.containsNonZero(value)) - return Stream.of(Tuples.staticArityFlatTupleOf(value)); - else - return Stream.empty(); - } - } - - @Override - public Iterable enumerateValues(TupleMask seedMask, ITuple seed) { - if (seedMask.getSize() == 0) { // unseeded - return values; - } else { - throw new IllegalArgumentException(seedMask.toString()); - } - } - @Override - public Stream streamValues(TupleMask seedMask, ITuple seed) { - if (seedMask.getSize() == 0) { // unseeded - return values.asStream(); - } else { - throw new IllegalArgumentException(seedMask.toString()); - } - } - - -} diff --git a/subprojects/viatra-runtime/build.gradle.kts b/subprojects/viatra-runtime/build.gradle.kts index 5d6e3de6..b1e65c94 100644 --- a/subprojects/viatra-runtime/build.gradle.kts +++ b/subprojects/viatra-runtime/build.gradle.kts @@ -9,9 +9,7 @@ plugins { } dependencies { - api(project(":refinery-viatra-runtime-base")) - api(libs.ecore) - implementation(libs.eclipse) - implementation(libs.emf) + api(project(":refinery-viatra-runtime-matchers")) + api(project(":refinery-viatra-runtime-base-itc")) implementation(libs.slf4j.log4j) } diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/IExtensions.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/IExtensions.java deleted file mode 100644 index d5e0d51f..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/IExtensions.java +++ /dev/null @@ -1,24 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004-2010 Gabor Bergmann, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime; - -/** - * Interface for storing string constants related to VIATRA Query's extension points. - * - * @author Istvan Rath - * - */ -public interface IExtensions { - - public static final String QUERY_SPECIFICATION_EXTENSION_POINT_ID = ViatraQueryRuntimePlugin.PLUGIN_ID + ".queryspecification"; - - public static final String INJECTOREXTENSIONID = ViatraQueryRuntimePlugin.PLUGIN_ID + ".injectorprovider"; - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/ViatraQueryRuntimePlugin.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/ViatraQueryRuntimePlugin.java deleted file mode 100644 index 5fbcdad0..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/ViatraQueryRuntimePlugin.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004-2010 Gabor Bergmann and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime; - -import org.eclipse.core.runtime.Plugin; -import tools.refinery.viatra.runtime.internal.ExtensionBasedSurrogateQueryLoader; -import tools.refinery.viatra.runtime.internal.ExtensionBasedSystemDefaultBackendLoader; -import tools.refinery.viatra.runtime.registry.ExtensionBasedQuerySpecificationLoader; -import org.osgi.framework.BundleContext; - -/** - * The activator class controls the plug-in life cycle - */ -public class ViatraQueryRuntimePlugin extends Plugin { - - public static final String PLUGIN_ID = "tools.refinery.viatra.runtime"; - - @Override - public void start(BundleContext context) throws Exception { - super.start(context); - ExtensionBasedSurrogateQueryLoader.instance().loadKnownSurrogateQueriesIntoRegistry(); - ExtensionBasedQuerySpecificationLoader.getInstance().loadRegisteredQuerySpecificationsIntoRegistry(); - ExtensionBasedSystemDefaultBackendLoader.instance().loadKnownBackends(); - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/AdvancedViatraQueryEngine.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/AdvancedViatraQueryEngine.java index 21e7dfa3..32a3430d 100644 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/AdvancedViatraQueryEngine.java +++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/AdvancedViatraQueryEngine.java @@ -3,32 +3,27 @@ * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-v20.html. - * + * * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ package tools.refinery.viatra.runtime.api; -import java.lang.reflect.InvocationTargetException; -import java.util.concurrent.Callable; - import tools.refinery.viatra.runtime.api.scope.QueryScope; -import tools.refinery.viatra.runtime.emf.EMFScope; import tools.refinery.viatra.runtime.internal.apiimpl.ViatraQueryEngineImpl; import tools.refinery.viatra.runtime.matchers.ViatraQueryRuntimeException; -import tools.refinery.viatra.runtime.matchers.backend.IMatcherCapability; -import tools.refinery.viatra.runtime.matchers.backend.IQueryBackend; -import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendFactory; -import tools.refinery.viatra.runtime.matchers.backend.IQueryResultProvider; -import tools.refinery.viatra.runtime.matchers.backend.QueryEvaluationHint; +import tools.refinery.viatra.runtime.matchers.backend.*; + +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.Callable; /** * Advanced interface to a VIATRA incremental evaluation engine. - * + * *

* You can create a new, private, unmanaged {@link AdvancedViatraQueryEngine} instance using * {@link #createUnmanagedEngine(QueryScope)}. Additionally, you can access the advanced interface on any * {@link ViatraQueryEngine} by {@link AdvancedViatraQueryEngine#from(ViatraQueryEngine)}. - * + * *

* While the default interface {@link ViatraQueryEngine}, is suitable for most users, this advanced interface provides more * control over the engine. The most important added functionality is the following: @@ -45,29 +40,29 @@ import tools.refinery.viatra.runtime.matchers.backend.QueryEvaluationHint; * register a callback using {@link #addLifecycleListener(ViatraQueryEngineLifecycleListener)} to learn when another client * has called the destructive methods {@link #dispose()} or {@link #wipe()}. * - * + * * @author Bergmann Gabor * @noextend This class is not intended to be subclassed by clients. */ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { - + /** * Creates a new unmanaged VIATRA Query engine to evaluate queries over a given scope specified by an {@link QueryScope}. - * - *

Repeated invocations will return different instances, so other clients are unable to independently access - * and influence the returned engine. Note that unmanaged engines do not benefit from some performance improvements - * that stem from sharing incrementally maintained indices and caches between multiple clients using the same managed + * + *

Repeated invocations will return different instances, so other clients are unable to independently access + * and influence the returned engine. Note that unmanaged engines do not benefit from some performance improvements + * that stem from sharing incrementally maintained indices and caches between multiple clients using the same managed * engine instance. - * + * *

* Client is responsible for the lifecycle of the returned engine, hence the usage of the advanced interface * {@link AdvancedViatraQueryEngine}. - * + * *

* The match set of any patterns will be incrementally refreshed upon updates from this scope. - * - * @param scope - * the scope of query evaluation; the definition of the set of model elements that this engine is operates on. + * + * @param scope + * the scope of query evaluation; the definition of the set of model elements that this engine is operates on. * Provide e.g. a {@link EMFScope} for evaluating queries on an EMF model. * @return the advanced interface to a newly created unmanaged engine * @since 0.9 @@ -75,24 +70,24 @@ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { public static AdvancedViatraQueryEngine createUnmanagedEngine(QueryScope scope) { return new ViatraQueryEngineImpl(null, scope); } - + /** * Creates a new unmanaged VIATRA Query engine to evaluate queries over a given scope specified by an {@link QueryScope}. - * - *

Repeated invocations will return different instances, so other clients are unable to independently access - * and influence the returned engine. Note that unmanaged engines do not benefit from some performance improvements - * that stem from sharing incrementally maintained indices and caches between multiple clients using the same managed + * + *

Repeated invocations will return different instances, so other clients are unable to independently access + * and influence the returned engine. Note that unmanaged engines do not benefit from some performance improvements + * that stem from sharing incrementally maintained indices and caches between multiple clients using the same managed * engine instance. - * + * *

* Client is responsible for the lifecycle of the returned engine, hence the usage of the advanced interface * {@link AdvancedViatraQueryEngine}. - * + * *

* The match set of any patterns will be incrementally refreshed upon updates from this scope. - * - * @param scope - * the scope of query evaluation; the definition of the set of model elements that this engine is operates on. + * + * @param scope + * the scope of query evaluation; the definition of the set of model elements that this engine is operates on. * Provide e.g. a {@link EMFScope} for evaluating queries on an EMF model. * @return the advanced interface to a newly created unmanaged engine * @since 1.4 @@ -103,11 +98,11 @@ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { /** * Provides access to a given existing engine through the advanced interface. - * + * *

* Caveat: if the referenced engine is managed (i.e. created via {@link ViatraQueryEngine#on(QueryScope)}), the advanced * methods {@link #dispose()} and {@link #wipe()} will not be allowed. - * + * * @param engine * the engine to access using the advanced interface * @return a reference to the same engine conforming to the advanced interface @@ -118,7 +113,7 @@ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { /** * Add an engine lifecycle listener to this engine instance. - * + * * @param listener * the {@link ViatraQueryEngineLifecycleListener} that should listen to lifecycle events from this engine */ @@ -126,7 +121,7 @@ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { /** * Remove an existing lifecycle listener from this engine instance. - * + * * @param listener * the {@link ViatraQueryEngineLifecycleListener} that should not listen to lifecycle events from this * engine anymore @@ -136,7 +131,7 @@ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { /** * Add an model update event listener to this engine instance (that fires its callbacks according to its * notification level). - * + * * @param listener * the {@link ViatraQueryModelUpdateListener} that should listen to model update events from this engine. */ @@ -144,7 +139,7 @@ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { /** * Remove an existing model update event listener to this engine instance. - * + * * @param listener * the {@link ViatraQueryModelUpdateListener} that should not listen to model update events from this engine * anymore @@ -153,20 +148,20 @@ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { /** * Registers low-level callbacks for match appearance and disappearance on this pattern matcher. - * + * *

* Caution: This is a low-level callback that is invoked when the pattern matcher is not necessarily in a * consistent state yet. Importantly, no model modification permitted during the callback. Most users should use the * databinding support ({@link org.eclipse.viatra.addon.databinding.runtime.api.ViatraObservables ViatraObservables}) or the event-driven API * ({@link org.eclipse.viatra.transformation.evm.api.EventDrivenVM EventDrivenVM}) instead. - * + * *

* Performance note: expected to be much more efficient than polling at {@link #addCallbackAfterUpdates(Runnable)}, * but prone to "signal hazards", e.g. spurious match appearances that will disappear immediately afterwards. - * + * *

* The callback can be unregistered via {@link #removeCallbackOnMatchUpdate(IMatchUpdateListener)}. - * + * * @param fireNow * if true, appearCallback will be immediately invoked on all current matches as a one-time effect. See * also {@link ViatraQueryMatcher#forEachMatch(IMatchProcessor)}. @@ -180,7 +175,7 @@ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { /** * Remove an existing match update event listener to this engine instance. - * + * * @param matcher * the {@link ViatraQueryMatcher} for which this listener should not be active anymore * @param listener @@ -189,15 +184,15 @@ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { public abstract void removeMatchUpdateListener(ViatraQueryMatcher matcher, IMatchUpdateListener listener); - + /** - * Access a pattern matcher based on a {@link IQuerySpecification}, overriding some of the default query evaluation hints. - * Multiple calls may return the same matcher depending on the actual evaluation hints. - * - *

It is guaranteed that this method will always return a matcher instance which is functionally compatible - * with the requested functionality (see {@link IMatcherCapability}). + * Access a pattern matcher based on a {@link IQuerySpecification}, overriding some of the default query evaluation hints. + * Multiple calls may return the same matcher depending on the actual evaluation hints. + * + *

It is guaranteed that this method will always return a matcher instance which is functionally compatible + * with the requested functionality (see {@link IMatcherCapability}). * Otherwise, the query evaluator is free to ignore any hints. - * + * *

For stateful query backends (Rete), hints may be effective only the first time a matcher is created. * @param querySpecification a {@link IQuerySpecification} that describes a VIATRA query * @return a pattern matcher corresponding to the specification @@ -206,20 +201,20 @@ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { * @since 0.9 */ public abstract > Matcher getMatcher( - IQuerySpecification querySpecification, + IQuerySpecification querySpecification, QueryEvaluationHint optionalEvaluationHints); /** - * Initializes matchers for a group of patterns as one step (optionally overriding some of the default query evaluation hints). + * Initializes matchers for a group of patterns as one step (optionally overriding some of the default query evaluation hints). * If some of the pattern matchers are already * constructed in the engine, no task is performed for them. - * + * *

* This preparation step has the advantage that it prepares pattern matchers for an arbitrary number of patterns in a - * single-pass traversal of the model. - * This is typically more efficient than traversing the model each time an individual pattern matcher is initialized on demand. + * single-pass traversal of the model. + * This is typically more efficient than traversing the model each time an individual pattern matcher is initialized on demand. * The performance benefit only manifests itself if the engine is not in wildcard mode. - * + * * @param queryGroup a {@link IQueryGroup} identifying a set of VIATRA queries * @param optionalEvaluationHints additional / overriding options on query evaluation; passing null means default options associated with each query * @throws ViatraQueryRuntimeException @@ -227,23 +222,23 @@ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { * @since 0.9 */ public abstract void prepareGroup(IQueryGroup queryGroup, QueryEvaluationHint optionalEvaluationHints); - + /** * Indicates whether the engine is managed, i.e. the default engine assigned to the given scope root by * {@link ViatraQueryEngine#on(QueryScope)}. - * + * *

* If the engine is managed, there may be other clients using it, as all calls to * {@link ViatraQueryEngine#on(QueryScope)} return the same managed engine instance for a given scope root. Therefore the * destructive methods {@link #wipe()} and {@link #dispose()} are not allowed. - * + * *

* On the other hand, if the engine is unmanaged (i.e. a private instance created using * {@link #createUnmanagedEngine(QueryScope)}), then {@link #wipe()} and {@link #dispose()} can be called. If you * explicitly share a private, unmanaged engine between multiple sites, register a callback using * {@link #addLifecycleListener(ViatraQueryEngineLifecycleListener)} to learn when another client has called these * destructive methods. - * + * * @return true if the engine is managed, and therefore potentially shared with other clients querying the same EMF * model */ @@ -252,11 +247,11 @@ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { /** * Indicates whether the engine is in a tainted, inconsistent state due to some internal errors. If true, results * are no longer reliable; engine should be disposed. - * + * *

* The engine is in a tainted state if any of its internal processes report back a fatal error. The * {@link ViatraQueryEngineLifecycleListener} interface provides a callback method for entering the tainted state. - * + * * @return the tainted state */ public abstract boolean isTainted(); @@ -265,7 +260,7 @@ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { * Discards any pattern matcher caches and forgets known patterns. The base index built directly on the underlying * EMF model, however, is kept in memory to allow reuse when new pattern matchers are built. Use this method if you * have e.g. new versions of the same patterns, to be matched on the same model. - * + * *

* Matcher objects will continue to return stale results. If no references are retained to the matchers, they can * eventually be GC'ed. @@ -275,7 +270,7 @@ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { * If you explicitly share a private, unmanaged engine between multiple sites, register a callback using * {@link #addLifecycleListener(ViatraQueryEngineLifecycleListener)} to learn when another client has called this * destructive method. - * + * * @throws UnsupportedOperationException * if engine is managed */ @@ -295,12 +290,12 @@ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { * If you explicitly share a private, unmanaged engine between multiple sites, register a callback using * {@link #addLifecycleListener(ViatraQueryEngineLifecycleListener)} to learn when another client has called this * destructive method. - * + * * @throws UnsupportedOperationException * if engine is managed */ public abstract void dispose(); - + /** * Provides access to the selected query backend component of the VIATRA Query engine. * @noreference for internal use only @@ -316,45 +311,45 @@ public abstract class AdvancedViatraQueryEngine extends ViatraQueryEngine { * @since 1.4 */ public abstract > Matcher getExistingMatcher(IQuerySpecification querySpecification, QueryEvaluationHint optionalOverrideHints); - + /** * Returns the immutable {@link ViatraQueryEngineOptions} of the engine. - * + * * @return the engine options * @since 1.4 */ public abstract ViatraQueryEngineOptions getEngineOptions(); - + /** * Return the underlying result provider for the given matcher. - * + * * @beta This method may change in future versions * @since 1.4 * @noreference This method is considered internal API */ public abstract IQueryResultProvider getResultProviderOfMatcher(ViatraQueryMatcher matcher); - + /** - * The given callable will be executed, and all update propagation in stateful query backends + * The given callable will be executed, and all update propagation in stateful query backends * will be delayed until the execution is done. Within the callback, these backends will provide stale results. - * - *

It is optional for a {@link IQueryBackend} to support the delaying of update propagation; stateless backends will display up-to-date results. - * In this case, the given callable shall be executed, and the update propagation shall happen just like in non-delayed execution. - * - *

Example: in the Rete network, no messages will be propagated until the given callable is executed. - * After the execution of the callable, all accumulated messages will be delivered. - * + * + *

It is optional for a {@link IQueryBackend} to support the delaying of update propagation; stateless backends will display up-to-date results. + * In this case, the given callable shall be executed, and the update propagation shall happen just like in non-delayed execution. + * + *

Example: in the Rete network, no messages will be propagated until the given callable is executed. + * After the execution of the callable, all accumulated messages will be delivered. + * *

The purpose of this method is that stateful query backends may save work when multiple model modifications are performed within the callback that partially cancel each other out. - * + * * @param callable the callable to be executed * @return the result of the callable * @since 1.6 */ public abstract V delayUpdatePropagation(Callable callable) throws InvocationTargetException; - + /** - * Returns true if the update propagation in this engine is currently delayed, false otherwise. - * + * Returns true if the update propagation in this engine is currently delayed, false otherwise. + * * @see {@link #delayUpdatePropagation(Callable)} * @since 1.6 */ diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/IModelConnectorTypeEnum.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/IModelConnectorTypeEnum.java deleted file mode 100644 index e672a6e2..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/IModelConnectorTypeEnum.java +++ /dev/null @@ -1,18 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Andras Okros, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.api; - -/** - * This enum represents the possible notifier types which a model input should provide for the ui. - */ -public enum IModelConnectorTypeEnum { - - RESOURCESET, RESOURCE; - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/IQuerySpecification.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/IQuerySpecification.java index 9b84b031..326d2202 100644 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/IQuerySpecification.java +++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/IQuerySpecification.java @@ -3,14 +3,13 @@ * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-v20.html. - * + * * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ package tools.refinery.viatra.runtime.api; import tools.refinery.viatra.runtime.api.scope.QueryScope; -import tools.refinery.viatra.runtime.emf.EMFScope; import tools.refinery.viatra.runtime.matchers.ViatraQueryRuntimeException; import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery; import tools.refinery.viatra.runtime.matchers.psystem.queries.PQueryHeader; @@ -18,8 +17,8 @@ import tools.refinery.viatra.runtime.matchers.psystem.queries.PQueryHeader; /** * API interface for a VIATRA query specification. Each query is associated with a pattern. Methods instantiate a matcher * of the pattern with various parameters. - * - *

As of 0.9.0, some internal details (mostly relevant for query evaluator backends) have been moved to {@link #getInternalQueryRepresentation()}. + * + *

As of 0.9.0, some internal details (mostly relevant for query evaluator backends) have been moved to {@link #getInternalQueryRepresentation()}. * * @author Bergmann Gábor * @@ -39,49 +38,49 @@ public interface IQuerySpecificationThe returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. - * + * * @param parameters * the fixed value of pattern parameters, or null if not bound. * @return the (partial) match object. */ public abstract IPatternMatch newMatch(Object... parameters); - + /** * The query is formulated over this kind of modeling platform. * E.g. for queries over EMF models, the {@link EMFScope} class is returned. */ public Class getPreferredScopeClass(); - + /** - * Returns the definition of the query in a format intended for consumption by the query evaluator. + * Returns the definition of the query in a format intended for consumption by the query evaluator. * @return the internal representation of the query. */ public PQuery getInternalQueryRepresentation(); - + /** * Creates a new uninitialized matcher, which is not functional until an engine initializes it. Clients * should not call this method, it is used by the {@link ViatraQueryEngine} instance to instantiate matchers. - * @throws ViatraQueryRuntimeException + * @throws ViatraQueryRuntimeException * @noreference This method is not intended to be referenced by clients. * @since 1.4 */ public Matcher instantiate(); - + } diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/IRunOnceQueryEngine.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/IRunOnceQueryEngine.java deleted file mode 100644 index b625980b..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/IRunOnceQueryEngine.java +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Abel Hegedus, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.api; - -import java.util.Collection; - -import org.eclipse.emf.common.notify.Notifier; -import tools.refinery.viatra.runtime.base.api.BaseIndexOptions; -import tools.refinery.viatra.runtime.base.api.NavigationHelper; - -/** - * A run-once query engine is used to get matches for queries without incremental support. - * Users can create a query engine with a given {@link Notifier} as scope and use a query specification - * to retrieve the current match set with this scope (see {@link #getAllMatches}). - * - * @author Abel Hegedus - * - */ -public interface IRunOnceQueryEngine { - - /** - * Returns the set of all matches for the given query in the scope of the engine. - * - * @param querySpecification the query that is evaluated - * @return matches represented as a Match object. - */ - Collection getAllMatches( - final IQuerySpecification> querySpecification); - - /** - * @return the scope of pattern matching, i.e. the root of the EMF model tree that this engine is attached to. - */ - Notifier getScope(); - - /** - * The base index options specifies how the base index is built, including wildcard mode (defaults to false) and - * dynamic EMF mode (defaults to false). See {@link NavigationHelper} for the explanation of wildcard mode and - * dynamic EMF mode. - * - *

The returned options can be modified in order to affect subsequent calls of {@link #getAllMatches}. - * - * @return the base index options used by the engine. - */ - BaseIndexOptions getBaseIndexOptions(); - - /** - * When set to true, the run-once query engine will not dispose it's engine and will resample the values of derived - * features before returning matches if the model changed since the last call. - * - * If the values of derived features may change without any model modification, call {@link #resampleOnNextCall()} - * before subsequent calls of {@link #getAllMatches}. - * - * @param automaticResampling - */ - void setAutomaticResampling(boolean automaticResampling); - - /** - * If automatic resampling is enabled and the value of derived features may change without model modifications, - * calling this method will make sure that re-sampling will occur before returning match results. - */ - void resampleOnNextCall(); -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/LazyLoadingQueryGroup.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/LazyLoadingQueryGroup.java deleted file mode 100644 index 6ae44b7c..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/LazyLoadingQueryGroup.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Zoltan Ujhelyi, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.api; - -import java.util.Collections; -import java.util.Objects; -import java.util.Set; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -import tools.refinery.viatra.runtime.api.impl.BaseQueryGroup; -import tools.refinery.viatra.runtime.matchers.util.Preconditions; -import tools.refinery.viatra.runtime.util.ViatraQueryLoggingUtil; - -/** - * Initializes a query group from a set of query providers. The query providers are not executed until the queries - * themselves are asked in the {@link #getSpecifications()} method. - * - * @author Zoltan Ujhelyi - * @since 1.3 - * - */ -public class LazyLoadingQueryGroup extends BaseQueryGroup { - - private final Set>> providers; - private Set> specifications = null; - - /** - * @param providers a non-null set to initialize the group - */ - public LazyLoadingQueryGroup(Set>> providers) { - Preconditions.checkArgument(providers != null, "The set of providers must not be null"); - this.providers = providers; - } - - /** - * @param providers a non-null set to initialize the group - */ - public static IQueryGroup of(Set>> querySpecifications) { - return new LazyLoadingQueryGroup(querySpecifications); - } - - @Override - public Set> getSpecifications() { - if (specifications == null) { - try { - specifications = providers.stream().filter(Objects::nonNull).map(Supplier::get).filter(Objects::nonNull).collect(Collectors.toSet()); - } catch (Exception e) { - // TODO maybe store in issue list and provide better error reporting in general - String errorMessage = "Exception occurred while accessing query specification from provider: " + e.getMessage(); - ViatraQueryLoggingUtil.getLogger(getClass()).error(errorMessage); - return Collections.emptySet(); - } - } - return specifications; - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/PackageBasedQueryGroup.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/PackageBasedQueryGroup.java deleted file mode 100644 index 252bb7fd..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/PackageBasedQueryGroup.java +++ /dev/null @@ -1,133 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2012, Abel Hegedus, Mark Czotter, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.api; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import tools.refinery.viatra.runtime.api.impl.BaseQueryGroup; -import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistry; -import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistryEntry; -import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistryChangeListener; -import tools.refinery.viatra.runtime.registry.IRegistryView; -import tools.refinery.viatra.runtime.registry.IRegistryViewFilter; -import tools.refinery.viatra.runtime.registry.QuerySpecificationRegistry; - -/** - * Package based {@link BaseQueryGroup} implementation. It handles patterns as a group within the same package. - * - * @author Abel Hegedus, Mark Czotter - * - */ -public class PackageBasedQueryGroup extends BaseQueryGroup { - - private final Set> querySpecifications = new HashSet<>(); - private final String packageName; - private final boolean includeSubPackages; - private IRegistryView view; - - /** - * Creates a query group with specifications of a given package from the {@link QuerySpecificationRegistry}. Only - * query specifications with the exact package fully qualified name are included. - * - * @param packageName - * that contains the specifications - */ - public PackageBasedQueryGroup(String packageName) { - this(packageName, false); - } - - /** - * Creates a query group with specifications of a given package from the {@link QuerySpecificationRegistry}. - * - * @param packageName - * that contain the specifications - * @param includeSubPackages - * if true all query specifications with package names starting with the given package are included - */ - public PackageBasedQueryGroup(String packageName, boolean includeSubPackages) { - super(); - this.packageName = packageName; - this.includeSubPackages = includeSubPackages; - IQuerySpecificationRegistry registry = QuerySpecificationRegistry.getInstance(); - view = registry.createView(new PackageNameBasedViewFilter()); - for (IQuerySpecificationRegistryEntry entry : view.getEntries()) { - this.querySpecifications.add(entry.get()); - } - SpecificationSetUpdater listener = new SpecificationSetUpdater(); - view.addViewListener(listener); - } - - @Override - public Set> getSpecifications() { - return Collections.unmodifiableSet(new HashSet<>(querySpecifications)); - } - - public String getPackageName() { - return packageName; - } - - public boolean isIncludeSubPackages() { - return includeSubPackages; - } - - /** - * Refreshes the pattern group from the query specification registry based on the parameters used during the - * initialization. - */ - public void refresh() { - // do nothing, view is automatically refreshed - } - - /** - * Listener to update the specification set - * - * @author Abel Hegedus - * - */ - private final class SpecificationSetUpdater implements IQuerySpecificationRegistryChangeListener { - @Override - public void entryAdded(IQuerySpecificationRegistryEntry entry) { - querySpecifications.add(entry.get()); - } - - @Override - public void entryRemoved(IQuerySpecificationRegistryEntry entry) { - querySpecifications.remove(entry.get()); - } - } - - /** - * Registry view filter that checks FQNs against the given package name. - * - * @author Abel Hegedus - * - */ - private final class PackageNameBasedViewFilter implements IRegistryViewFilter { - @Override - public boolean isEntryRelevant(IQuerySpecificationRegistryEntry entry) { - String fqn = entry.getFullyQualifiedName(); - if (packageName.length() + 1 < fqn.length()) { - if (includeSubPackages) { - if (fqn.startsWith(packageName + '.')) { - return true; - } - } else { - String name = fqn.substring(fqn.lastIndexOf('.') + 1, fqn.length()); - if (fqn.equals(packageName + '.' + name)) { - return true; - } - } - } - return false; - } - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngine.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngine.java index fd8ff848..ebae57a7 100644 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngine.java +++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngine.java @@ -12,8 +12,6 @@ package tools.refinery.viatra.runtime.api; import org.eclipse.emf.common.notify.Notifier; import tools.refinery.viatra.runtime.api.scope.IBaseIndex; import tools.refinery.viatra.runtime.api.scope.QueryScope; -import tools.refinery.viatra.runtime.base.api.BaseIndexOptions; -import tools.refinery.viatra.runtime.emf.EMFScope; import tools.refinery.viatra.runtime.matchers.ViatraQueryRuntimeException; import java.util.Set; diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngineManager.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngineManager.java index ca709b02..4a256aea 100644 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngineManager.java +++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngineManager.java @@ -3,47 +3,42 @@ * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-v20.html. - * + * * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ package tools.refinery.viatra.runtime.api; -import static tools.refinery.viatra.runtime.matchers.util.Preconditions.checkArgument; - -import java.lang.ref.WeakReference; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.WeakHashMap; - import tools.refinery.viatra.runtime.api.scope.QueryScope; -import tools.refinery.viatra.runtime.emf.EMFScope; import tools.refinery.viatra.runtime.internal.apiimpl.ViatraQueryEngineImpl; import tools.refinery.viatra.runtime.util.ViatraQueryLoggingUtil; +import java.lang.ref.WeakReference; +import java.util.*; + +import static tools.refinery.viatra.runtime.matchers.util.Preconditions.checkArgument; + /** * Global registry of active VIATRA Query Engines. - * + * *

* Manages an {@link ViatraQueryEngine} for each model (more precisely scope), that is created on demand. Managed engines are shared between * clients querying the same model. - * + * *

* It is also possible to create private, unmanaged engines that are not shared between clients. - * + * *

* Only weak references are retained on the managed engines. So if there are no other references to the matchers or the * engine, they can eventually be GC'ed, and they won't block the model from being GC'ed either. - * - * + * + * * @author Bergmann Gabor - * + * */ public class ViatraQueryEngineManager { private static ViatraQueryEngineManager instance = new ViatraQueryEngineManager(); - + /** * @return the singleton instance @@ -68,32 +63,32 @@ public class ViatraQueryEngineManager { } /** - * Creates a managed VIATRA Query Engine at a given scope (e.g. an EMF Resource or ResourceSet, as in {@link EMFScope}) - * or retrieves an already existing one. Repeated invocations for a single model root will return the same engine. + * Creates a managed VIATRA Query Engine at a given scope (e.g. an EMF Resource or ResourceSet, as in {@link EMFScope}) + * or retrieves an already existing one. Repeated invocations for a single model root will return the same engine. * Consequently, the engine will be reused between different clients querying the same model, providing performance benefits. - * + * *

* The match set of any patterns will be incrementally refreshed upon updates from this scope. - * - * @param scope - * the scope of query evaluation; the definition of the set of model elements that this engine is operates on. + * + * @param scope + * the scope of query evaluation; the definition of the set of model elements that this engine is operates on. * Provide e.g. a {@link EMFScope} for evaluating queries on an EMF model. * @return a new or previously existing engine */ public ViatraQueryEngine getQueryEngine(QueryScope scope) { return getQueryEngine(scope, ViatraQueryEngineOptions.getDefault()); } - + /** - * Creates a managed VIATRA Query Engine at a given scope (e.g. an EMF Resource or ResourceSet, as in {@link EMFScope}) - * or retrieves an already existing one. Repeated invocations for a single model root will return the same engine. + * Creates a managed VIATRA Query Engine at a given scope (e.g. an EMF Resource or ResourceSet, as in {@link EMFScope}) + * or retrieves an already existing one. Repeated invocations for a single model root will return the same engine. * Consequently, the engine will be reused between different clients querying the same model, providing performance benefits. - * + * *

* The match set of any patterns will be incrementally refreshed upon updates from this scope. - * - * @param scope - * the scope of query evaluation; the definition of the set of model elements that this engine is operates on. + * + * @param scope + * the scope of query evaluation; the definition of the set of model elements that this engine is operates on. * Provide e.g. a {@link EMFScope} for evaluating queries on an EMF model. * @return a new or previously existing engine * @since 1.4 @@ -110,9 +105,9 @@ public class ViatraQueryEngineManager { /** * Retrieves an already existing managed VIATRA Query Engine. - * - * @param scope - * the scope of query evaluation; the definition of the set of model elements that this engine is operates on. + * + * @param scope + * the scope of query evaluation; the definition of the set of model elements that this engine is operates on. * Provide e.g. a {@link EMFScope} for evaluating queries on an EMF model. * @return a previously existing engine, or null if no engine is active for the given EMF model root */ @@ -122,7 +117,7 @@ public class ViatraQueryEngineManager { /** * Collects all {@link ViatraQueryEngine} instances that still exist. - * + * * @return set of engines if there is any, otherwise EMTPY_SET */ public Set getExistingQueryEngines(){ @@ -139,14 +134,14 @@ public class ViatraQueryEngineManager { } return existingEngines; } - + private final Set initializationListeners; - + /** * Registers a listener for new engine initialization. - * + * *

For removal, use {@link #removeQueryEngineInitializationListener} - * + * * @param listener the listener to register */ public void addQueryEngineInitializationListener(ViatraQueryEngineInitializationListener listener) { @@ -156,7 +151,7 @@ public class ViatraQueryEngineManager { /** * Removes a registered listener added with {@link #addQueryEngineInitializationListener} - * + * * @param listener */ public void removeQueryEngineInitializationListener(ViatraQueryEngineInitializationListener listener) { @@ -166,7 +161,7 @@ public class ViatraQueryEngineManager { /** * Notifies listeners that a new engine has been initialized. - * + * * @param engine the initialized engine */ protected void notifyInitializationListeners(AdvancedViatraQueryEngine engine) { diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/BaseGeneratedEMFPQuery.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/BaseGeneratedEMFPQuery.java deleted file mode 100644 index c1fb0622..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/BaseGeneratedEMFPQuery.java +++ /dev/null @@ -1,110 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Bergmann Gabor, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.api.impl; - -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EClassifier; -import org.eclipse.emf.ecore.EEnum; -import org.eclipse.emf.ecore.EEnumLiteral; -import org.eclipse.emf.ecore.EPackage; -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.exception.ViatraQueryException; -import tools.refinery.viatra.runtime.matchers.psystem.queries.BasePQuery; -import tools.refinery.viatra.runtime.matchers.psystem.queries.PVisibility; -import tools.refinery.viatra.runtime.matchers.psystem.queries.QueryInitializationException; - -/** - * Common superclass for EMF-based generated PQueries. - * @author Bergmann Gabor - * - */ -public abstract class BaseGeneratedEMFPQuery extends BasePQuery { - - public BaseGeneratedEMFPQuery() { - this(PVisibility.PUBLIC); - } - - /** - * @since 2.0 - */ - public BaseGeneratedEMFPQuery(PVisibility visibility) { - super(visibility); - } - - protected QueryInitializationException processDependencyException(ViatraQueryException ex) { - if (ex.getCause() instanceof QueryInitializationException) - return (QueryInitializationException) ex.getCause(); - return new QueryInitializationException( - "Failed to initialize external dependencies of query specification - see 'caused by' for details.", - null, "Problem with query dependencies.", this, ex); - } - - protected EClassifier getClassifierLiteral(String packageUri, String classifierName) { - EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(packageUri); - if (ePackage == null) - throw new QueryInitializationException( - "Query refers to EPackage {1} not found in EPackage Registry.", - new String[]{packageUri}, - "Query refers to missing EPackage.", this); - EClassifier literal = ePackage.getEClassifier(classifierName); - if (literal == null) - throw new QueryInitializationException( - "Query refers to classifier {1} not found in EPackage {2}.", - new String[]{classifierName, packageUri}, - "Query refers to missing type in EPackage.", this); - return literal; - } - - /** - * For parameter type retrieval only. - * - *

If parameter type declaration is erroneous, we still get a working parameter list (without the type declaration); - * the exception will be thrown again later when the body is processed. - */ - protected EClassifier getClassifierLiteralSafe(String packageURI, String classifierName) { - try { - return getClassifierLiteral(packageURI, classifierName); - } catch (QueryInitializationException e) { - return null; - } - } - - protected EStructuralFeature getFeatureLiteral(String packageUri, String className, String featureName) { - EClassifier container = getClassifierLiteral(packageUri, className); - if (! (container instanceof EClass)) - throw new QueryInitializationException( - "Query refers to EClass {1} in EPackage {2} which turned out not be an EClass.", - new String[]{className, packageUri}, - "Query refers to missing EClass.", this); - EStructuralFeature feature = ((EClass)container).getEStructuralFeature(featureName); - if (feature == null) - throw new QueryInitializationException( - "Query refers to feature {1} not found in EClass {2}.", - new String[]{featureName, className}, - "Query refers to missing feature.", this); - return feature; - } - - protected EEnumLiteral getEnumLiteral(String packageUri, String enumName, String literalName) { - EClassifier enumContainer = getClassifierLiteral(packageUri, enumName); - if (! (enumContainer instanceof EEnum)) - throw new QueryInitializationException( - "Query refers to EEnum {1} in EPackage {2} which turned out not be an EEnum.", - new String[]{enumName, packageUri}, - "Query refers to missing enumeration type.", this); - EEnumLiteral literal = ((EEnum)enumContainer).getEEnumLiteral(literalName); - if (literal == null) - throw new QueryInitializationException( - "Query refers to enumeration literal {1} not found in EEnum {2}.", - new String[]{literalName, enumName}, - "Query refers to missing enumeration literal.", this); - return literal; - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/BaseGeneratedEMFQuerySpecification.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/BaseGeneratedEMFQuerySpecification.java deleted file mode 100644 index 9956983d..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/BaseGeneratedEMFQuerySpecification.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004-2010 Gabor Bergmann and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.api.impl; - -import tools.refinery.viatra.runtime.api.IPatternMatch; -import tools.refinery.viatra.runtime.api.ViatraQueryMatcher; -import tools.refinery.viatra.runtime.api.scope.QueryScope; -import tools.refinery.viatra.runtime.emf.EMFScope; -import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery; - -/** - * Provides common functionality of pattern-specific generated query specifications over the EMF scope. - * - * @author Bergmann Gábor - * @author Mark Czotter - */ -public abstract class BaseGeneratedEMFQuerySpecification> extends - BaseQuerySpecification { - - - /** - * Instantiates query specification for the given internal query representation. - */ - public BaseGeneratedEMFQuerySpecification(PQuery wrappedPQuery) { - super(wrappedPQuery); - } - - @Override - public Class getPreferredScopeClass() { - return EMFScope.class; - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/BaseGeneratedEMFQuerySpecificationWithGenericMatcher.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/BaseGeneratedEMFQuerySpecificationWithGenericMatcher.java deleted file mode 100644 index 949dd112..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/BaseGeneratedEMFQuerySpecificationWithGenericMatcher.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2017, Zoltan Ujhelyi, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.api.impl; - -import tools.refinery.viatra.runtime.api.GenericPatternMatch; -import tools.refinery.viatra.runtime.api.GenericPatternMatcher; -import tools.refinery.viatra.runtime.api.GenericQuerySpecification; -import tools.refinery.viatra.runtime.api.ViatraQueryEngine; -import tools.refinery.viatra.runtime.api.scope.QueryScope; -import tools.refinery.viatra.runtime.emf.EMFScope; -import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery; - -/** - * Provides common functionality of pattern-specific generated query specifications for without generated - * pattern-specific match and matcher classes, including private patterns. - * - * @since 1.7 - * - */ -public abstract class BaseGeneratedEMFQuerySpecificationWithGenericMatcher - extends GenericQuerySpecification { - - public BaseGeneratedEMFQuerySpecificationWithGenericMatcher(PQuery wrappedPQuery) { - super(wrappedPQuery); - } - - @Override - public Class getPreferredScopeClass() { - return EMFScope.class; - } - - @Override - protected GenericPatternMatcher instantiate(final ViatraQueryEngine engine) { - return defaultInstantiate(engine); - } - - @Override - public GenericPatternMatcher instantiate() { - return new GenericPatternMatcher(this); - } - - @Override - public GenericPatternMatch newEmptyMatch() { - return GenericPatternMatch.newEmptyMatch(this); - } - - @Override - public GenericPatternMatch newMatch(final Object... parameters) { - return GenericPatternMatch.newMatch(this, parameters); - } - -} \ No newline at end of file diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/BasePatternMatch.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/BasePatternMatch.java index 7690daf6..182bb466 100644 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/BasePatternMatch.java +++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/BasePatternMatch.java @@ -3,25 +3,23 @@ * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-v20.html. - * + * * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ package tools.refinery.viatra.runtime.api.impl; +import tools.refinery.viatra.runtime.api.IPatternMatch; + import java.util.Arrays; import java.util.Collections; import java.util.List; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.api.IPatternMatch; - /** * Base implementation of IPatternMatch. - * + * * @author Bergmann Gábor - * + * */ public abstract class BasePatternMatch implements IPatternMatch { @@ -29,36 +27,14 @@ public abstract class BasePatternMatch implements IPatternMatch { protected static List makeImmutableList(T... elements) { return Collections.unmodifiableList(Arrays.asList(elements)); } - + public static String prettyPrintValue(Object o) { if (o == null) { return "(null)"; } - String name = prettyPrintFeature(o, "name"); - if (name != null) { - return name; - } - /* - * if (o instanceof EObject) { EStructuralFeature feature = ((EObject)o).eClass().getEStructuralFeature("name"); - * if (feature != null) { Object name = ((EObject)o).eGet(feature); if (name != null) return name.toString(); } - * } - */ return o.toString(); } - public static String prettyPrintFeature(Object o, String featureName) { - if (o instanceof EObject) { - EStructuralFeature feature = ((EObject) o).eClass().getEStructuralFeature(featureName); - if (feature != null) { - Object value = ((EObject) o).eGet(feature); - if (value != null) { - return value.toString(); - } - } - } - return null; - } - // TODO performance can be improved here somewhat @Override @@ -83,7 +59,7 @@ public abstract class BasePatternMatch implements IPatternMatch { public String toString() { return "Match<" + patternName() + ">{" + prettyPrint() + "}"; } - + @Override public boolean isCompatibleWith(IPatternMatch other) { if(other == null) { @@ -102,7 +78,7 @@ public abstract class BasePatternMatch implements IPatternMatch { } return true; } - + @Override public String patternName() { return specification().getFullyQualifiedName(); diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/RunOnceQueryEngine.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/RunOnceQueryEngine.java deleted file mode 100644 index a97dea5d..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/impl/RunOnceQueryEngine.java +++ /dev/null @@ -1,140 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2013, Abel Hegedus, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.api.impl; - -import java.util.Collection; - -import org.eclipse.emf.common.notify.Notifier; -import tools.refinery.viatra.runtime.api.AdvancedViatraQueryEngine; -import tools.refinery.viatra.runtime.api.IPatternMatch; -import tools.refinery.viatra.runtime.api.IQuerySpecification; -import tools.refinery.viatra.runtime.api.IRunOnceQueryEngine; -import tools.refinery.viatra.runtime.api.ViatraQueryEngine; -import tools.refinery.viatra.runtime.api.ViatraQueryMatcher; -import tools.refinery.viatra.runtime.api.ViatraQueryModelUpdateListener; -import tools.refinery.viatra.runtime.base.api.BaseIndexOptions; -import tools.refinery.viatra.runtime.emf.EMFScope; - -/** - * Run-once query engines can be used to retrieve the current match set of query specifications - * in a given scope. The engine is initialized with a {@link Notifier} as scope and a base index options - * that specifically allows traversing derived features that are not well-behaving. - * - * @author Abel Hegedus - * - */ -public class RunOnceQueryEngine implements IRunOnceQueryEngine { - - /** - * If the model changes, we know that a resampling is required. - * - * @author Abel Hegedus - * - */ - private final class RunOnceSamplingModelUpdateListener implements ViatraQueryModelUpdateListener { - @Override - public void notifyChanged(ChangeLevel changeLevel) { - // any model change may require re-sampling - reSamplingNeeded = true; - } - - @Override - public ChangeLevel getLevel() { - return ChangeLevel.MODEL; - } - } - - /** - * Override the default base index options to allow traversing and indexing derived features - * that would be problematic in incremental evaluation. - * - * @author Abel Hegedus - * - */ - private static final class RunOnceBaseIndexOptions extends BaseIndexOptions { - - public RunOnceBaseIndexOptions() { - this.traverseOnlyWellBehavingDerivedFeatures = false; - } - - } - - /** - * The scope of the engine that is used when creating one-time {@link ViatraQueryEngine}s. - */ - private Notifier notifier; - /** - * The options that are used for initializing the {@link ViatraQueryEngine}. - */ - private RunOnceBaseIndexOptions baseIndexOptions; - private AdvancedViatraQueryEngine engine; - private boolean reSamplingNeeded = false; - protected boolean samplingMode = false; - private RunOnceSamplingModelUpdateListener modelUpdateListener; - - /** - * Creates a run-once query engine on the given notifier. - */ - public RunOnceQueryEngine(Notifier notifier) { - this.notifier = notifier; - this.baseIndexOptions = new RunOnceBaseIndexOptions(); - } - - @Override - public Collection getAllMatches( - IQuerySpecification> querySpecification) { - - if(samplingMode && reSamplingNeeded && engine != null) { - // engine exists from earlier, but may need resampling if model changed - engine.getBaseIndex().resampleDerivedFeatures(); - } else { - // create new engine if it doesn't exists - //TODO correct scope handling - engine = AdvancedViatraQueryEngine.createUnmanagedEngine(new EMFScope(notifier, baseIndexOptions)); - } - ViatraQueryMatcher matcher = engine.getMatcher(querySpecification); - Collection allMatches = matcher.getAllMatches(); - if(samplingMode) { - engine.addModelUpdateListener(modelUpdateListener); - } else { - engine.dispose(); - engine = null; - } - return allMatches; - } - - @Override - public BaseIndexOptions getBaseIndexOptions() { - return baseIndexOptions; - } - - @Override - public Notifier getScope() { - return notifier; - } - - @Override - public void setAutomaticResampling(boolean automaticResampling) { - samplingMode = automaticResampling; - if(automaticResampling) { - if (modelUpdateListener == null) { - modelUpdateListener = new RunOnceSamplingModelUpdateListener(); - } - } else if(engine != null) { - engine.dispose(); - engine = null; - } - } - - @Override - public void resampleOnNextCall() { - reSamplingNeeded = true; - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/scope/IIndexingErrorListener.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/scope/IIndexingErrorListener.java index d144bba6..f61a5edb 100644 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/scope/IIndexingErrorListener.java +++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/scope/IIndexingErrorListener.java @@ -3,17 +3,15 @@ * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-v20.html. - * + * * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ package tools.refinery.viatra.runtime.api.scope; -import tools.refinery.viatra.runtime.base.api.NavigationHelper; - /** - * + * * This interface contains callbacks for various internal errors from the {@link NavigationHelper base index}. - * + * * @author Zoltan Ujhelyi * @since 0.9 * diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/DynamicEMFQueryRuntimeContext.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/DynamicEMFQueryRuntimeContext.java deleted file mode 100644 index a6da213e..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/DynamicEMFQueryRuntimeContext.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Bergmann Gabor, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.emf; - -import org.apache.log4j.Logger; -import tools.refinery.viatra.runtime.base.api.NavigationHelper; -import tools.refinery.viatra.runtime.matchers.tuple.Tuple; -import tools.refinery.viatra.runtime.matchers.tuple.Tuples; - -/** - * In dynamic EMF mode, we need to make sure that EEnum literal constants and values returned by eval() expressions - * are canonicalized in the same way as enum literals from the EMF model. - * - *

This canonicalization is a one-way mapping, so - * {@link #unwrapElement(Object)} and {@link #unwrapTuple(Object)} remain NOPs. - * - * @author Bergmann Gabor - * - */ -public class DynamicEMFQueryRuntimeContext extends EMFQueryRuntimeContext { - - public DynamicEMFQueryRuntimeContext(NavigationHelper baseIndex, Logger logger, EMFScope emfScope) { - super(baseIndex, logger, emfScope); - } - - @Override - public Object wrapElement(Object externalElement) { - return baseIndex.toCanonicalValueRepresentation(externalElement); - } - - @Override - public Tuple wrapTuple(Tuple externalElements) { - Object[] elements = externalElements.getElements(); - for (int i=0; i< elements.length; ++i) - elements[i] = wrapElement(elements[i]); - return Tuples.flatTupleOf(elements); - } - - - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFBaseIndexWrapper.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFBaseIndexWrapper.java deleted file mode 100644 index 433c5f72..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFBaseIndexWrapper.java +++ /dev/null @@ -1,160 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2014, Bergmann Gabor, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.emf; - -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.Callable; - -import org.eclipse.emf.common.notify.Notification; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.api.scope.IBaseIndex; -import tools.refinery.viatra.runtime.api.scope.IIndexingErrorListener; -import tools.refinery.viatra.runtime.api.scope.IInstanceObserver; -import tools.refinery.viatra.runtime.api.scope.ViatraBaseIndexChangeListener; -import tools.refinery.viatra.runtime.base.api.EMFBaseIndexChangeListener; -import tools.refinery.viatra.runtime.base.api.IEMFIndexingErrorListener; -import tools.refinery.viatra.runtime.base.api.LightweightEObjectObserver; -import tools.refinery.viatra.runtime.base.api.NavigationHelper; - -/** - * Wraps the EMF base index into the IBaseIndex interface. - * @author Bergmann Gabor - * - */ -public class EMFBaseIndexWrapper implements IBaseIndex { - - private final NavigationHelper navigationHelper; - /** - * @return the underlying index object - */ - public NavigationHelper getNavigationHelper() { - return navigationHelper; - } - - /** - * @param navigationHelper - */ - public EMFBaseIndexWrapper(NavigationHelper navigationHelper) { - this.navigationHelper = navigationHelper; - } - - @Override - public void resampleDerivedFeatures() { - navigationHelper.resampleDerivedFeatures(); - } - - - @Override - public V coalesceTraversals(Callable callable) throws InvocationTargetException { - return navigationHelper.coalesceTraversals(callable); - } - - Map indexErrorListeners = - new HashMap(); - @Override - public boolean addIndexingErrorListener(final IIndexingErrorListener listener) { - if (indexErrorListeners.containsKey(listener)) return false; - IEMFIndexingErrorListener emfListener = new IEMFIndexingErrorListener() { - @Override - public void fatal(String description, Throwable t) { - listener.fatal(description, t); - } - @Override - public void error(String description, Throwable t) { - listener.error(description, t); - } - }; - indexErrorListeners.put(listener, emfListener); - return navigationHelper.addIndexingErrorListener(emfListener); - } - @Override - public boolean removeIndexingErrorListener(IIndexingErrorListener listener) { - if (!indexErrorListeners.containsKey(listener)) return false; - return navigationHelper.removeIndexingErrorListener(indexErrorListeners.remove(listener)); - } - - - Map indexChangeListeners = - new HashMap(); - @Override - public void addBaseIndexChangeListener(final ViatraBaseIndexChangeListener listener) { - EMFBaseIndexChangeListener emfListener = new EMFBaseIndexChangeListener() { - @Override - public boolean onlyOnIndexChange() { - return listener.onlyOnIndexChange(); - } - - @Override - public void notifyChanged(boolean indexChanged) { - listener.notifyChanged(indexChanged); - } - }; - indexChangeListeners.put(listener, emfListener); - navigationHelper.addBaseIndexChangeListener(emfListener); - } - @Override - public void removeBaseIndexChangeListener(ViatraBaseIndexChangeListener listener) { - final EMFBaseIndexChangeListener cListener = indexChangeListeners.remove(listener); - if (cListener != null) - navigationHelper.removeBaseIndexChangeListener(cListener); - } - - Map instanceObservers = - new HashMap(); - @Override - public boolean addInstanceObserver(final IInstanceObserver observer, - Object observedObject) { - if (observedObject instanceof EObject) { - EObjectObserver emfObserver = instanceObservers.computeIfAbsent(observer, EObjectObserver::new); - boolean success = - navigationHelper.addLightweightEObjectObserver(emfObserver, (EObject) observedObject); - if (success) emfObserver.usageCount++; - return success; - } else return false; - } - @Override - public boolean removeInstanceObserver(IInstanceObserver observer, - Object observedObject) { - if (observedObject instanceof EObject) { - EObjectObserver emfObserver = instanceObservers.get(observer); - if (emfObserver == null) - return false; - boolean success = - navigationHelper.removeLightweightEObjectObserver(emfObserver, (EObject)observedObject); - if (success) - if (0 == --emfObserver.usageCount) - instanceObservers.remove(observer); - return success; - } else return false; - } - private static class EObjectObserver implements LightweightEObjectObserver { - /** - * - */ - private final IInstanceObserver observer; - int usageCount = 0; - - /** - * @param observer - */ - private EObjectObserver(IInstanceObserver observer) { - this.observer = observer; - } - - @Override - public void notifyFeatureChanged(EObject host, - EStructuralFeature feature, Notification notification) { - observer.notifyBinaryChanged(host, feature); - } - } - -} \ No newline at end of file diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFEngineContext.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFEngineContext.java deleted file mode 100644 index 5fe9e23a..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFEngineContext.java +++ /dev/null @@ -1,110 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2014, Bergmann Gabor, Denes Harmath, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.emf; - -import org.apache.log4j.Logger; -import org.eclipse.emf.common.notify.Notifier; -import tools.refinery.viatra.runtime.api.ViatraQueryEngine; -import tools.refinery.viatra.runtime.api.scope.IBaseIndex; -import tools.refinery.viatra.runtime.api.scope.IEngineContext; -import tools.refinery.viatra.runtime.api.scope.IIndexingErrorListener; -import tools.refinery.viatra.runtime.base.api.ViatraBaseFactory; -import tools.refinery.viatra.runtime.base.api.NavigationHelper; -import tools.refinery.viatra.runtime.matchers.ViatraQueryRuntimeException; -import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContext; - -/** - * Implements an engine context on EMF models. - * @author Bergmann Gabor - * - */ -class EMFEngineContext implements IEngineContext { - - private final EMFScope emfScope; - ViatraQueryEngine engine; - Logger logger; - NavigationHelper navHelper; - IBaseIndex baseIndex; - IIndexingErrorListener taintListener; - private EMFQueryRuntimeContext runtimeContext; - - public EMFEngineContext(EMFScope emfScope, ViatraQueryEngine engine, IIndexingErrorListener taintListener, Logger logger) { - this.emfScope = emfScope; - this.engine = engine; - this.logger = logger; - this.taintListener = taintListener; - } - - /** - * @throws ViatraQueryRuntimeException thrown if the navigation helper cannot be initialized - */ - public NavigationHelper getNavHelper() { - return getNavHelper(true); - } - - private NavigationHelper getNavHelper(boolean ensureInitialized) { - if (navHelper == null) { - // sync to avoid crazy compiler reordering which would matter if derived features use VIATRA and call this - // reentrantly - synchronized (this) { - navHelper = ViatraBaseFactory.getInstance().createNavigationHelper(null, this.emfScope.getOptions(), - logger); - getBaseIndex().addIndexingErrorListener(taintListener); - } - - if (ensureInitialized) { - ensureIndexLoaded(); - } - - } - return navHelper; - } - - private void ensureIndexLoaded() { - for (Notifier scopeRoot : this.emfScope.getScopeRoots()) { - navHelper.addRoot(scopeRoot); - } - } - - @Override - public IQueryRuntimeContext getQueryRuntimeContext() { - NavigationHelper nh = getNavHelper(false); - if (runtimeContext == null) { - runtimeContext = - emfScope.getOptions().isDynamicEMFMode() ? - new DynamicEMFQueryRuntimeContext(nh, logger, emfScope) : - new EMFQueryRuntimeContext(nh, logger, emfScope); - - ensureIndexLoaded(); - } - - return runtimeContext; - } - - @Override - public void dispose() { - if (runtimeContext != null) runtimeContext.dispose(); - if (navHelper != null) navHelper.dispose(); - - this.baseIndex = null; - this.engine = null; - this.logger = null; - this.navHelper = null; - } - - - @Override - public IBaseIndex getBaseIndex() { - if (baseIndex == null) { - final NavigationHelper navigationHelper = getNavHelper(); - baseIndex = new EMFBaseIndexWrapper(navigationHelper); - } - return baseIndex; - } -} \ No newline at end of file diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFQueryMetaContext.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFQueryMetaContext.java deleted file mode 100644 index c316d308..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFQueryMetaContext.java +++ /dev/null @@ -1,405 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Bergmann Gabor, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.emf; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.eclipse.emf.common.util.EList; -import org.eclipse.emf.ecore.EAttribute; -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EClassifier; -import org.eclipse.emf.ecore.EDataType; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.EcorePackage; -import tools.refinery.viatra.runtime.emf.types.BaseEMFTypeKey; -import tools.refinery.viatra.runtime.emf.types.EClassTransitiveInstancesKey; -import tools.refinery.viatra.runtime.emf.types.EClassUnscopedTransitiveInstancesKey; -import tools.refinery.viatra.runtime.emf.types.EDataTypeInSlotsKey; -import tools.refinery.viatra.runtime.emf.types.EStructuralFeatureInstancesKey; -import tools.refinery.viatra.runtime.matchers.context.AbstractQueryMetaContext; -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.context.InputKeyImplication; -import tools.refinery.viatra.runtime.matchers.context.common.JavaTransitiveInstancesKey; - -/** - * The meta context information for EMF scopes. - * - *

The runtime context may specialize answers with a given scope. - * In a static context, a conservative default version ({@link #DEFAULT}) can be used instead. - * - *

TODO generics? - * @author Bergmann Gabor - * - */ -public final class EMFQueryMetaContext extends AbstractQueryMetaContext { - - /** - * Default static instance that only makes conservative assumptions that are valid for any {@link EMFScope} (but not if objects are used). - * @since 1.6 - */ - public static final EMFQueryMetaContext DEFAULT = new EMFQueryMetaContext(false, true, UnscopedTypeSupport.EMIT_ALWAYS); - - /** - * Default static instance that only makes conservative assumptions that are valid for any scope, even with surrogate objects. - * Unscoped types are used for inference, but not emitted as replacement candidates, as they cannot be checked at runtime. - * @since 2.1 - */ - public static final EMFQueryMetaContext DEFAULT_SURROGATE = new EMFQueryMetaContext(false, true, UnscopedTypeSupport.EMIT_EXCEPT_AS_WEAKENED_REPLACEMENT); - - - private static final EClass EOBJECT_CLASS = - EcorePackage.eINSTANCE.getEObject(); - private static final EClassTransitiveInstancesKey EOBJECT_SCOPED_KEY = - new EClassTransitiveInstancesKey(EOBJECT_CLASS); - private static final EClassUnscopedTransitiveInstancesKey EOBJECT_UNSCOPED_KEY = - new EClassUnscopedTransitiveInstancesKey(EOBJECT_CLASS); - - private boolean assumeNonDangling; - private boolean subResourceScopeSplit; - private UnscopedTypeSupport emitUnscopedEClassTypes; - - private enum UnscopedTypeSupport { - EMIT_ALWAYS, - EMIT_EXCEPT_AS_WEAKENED_REPLACEMENT, - EMIT_NEVER - } - - - /** - * Instantiates a specialized meta information that is aware of scope-specific details. - * Note that this API is not stable and thus non-public. - * - * @param assumeNonDangling assumes that all cross-references are non-dangling (do not lead out of scope), no matter what - * @param subResourceScopeSplit the scope granularity may be finer than resource-level, i.e. proxy-non-resolving references can lead out of scope - * @param emitUnscopedEClassTypes if requested, the metacontext will suppress unscoped input keys; this is recommended if surrogates are used instead of EObjects - */ - EMFQueryMetaContext(boolean assumeNonDangling, boolean subResourceScopeSplit, UnscopedTypeSupport emitUnscopedEClassTypes) { - this.assumeNonDangling = assumeNonDangling; - this.subResourceScopeSplit = subResourceScopeSplit; - this.emitUnscopedEClassTypes = emitUnscopedEClassTypes; - } - - /** - * Instantiates a specialized meta information that is aware of scope-specific details. - * @since 2.1 - */ - public EMFQueryMetaContext(EMFScope scope) { - this(scope.getOptions().isDanglingFreeAssumption(), - scope.getScopeRoots().size()==1 && scope.getScopeRoots().iterator().next() instanceof EObject, - UnscopedTypeSupport.EMIT_ALWAYS); - } - - - @Override - public boolean isEnumerable(IInputKey key) { - ensureValidKey(key); - return key.isEnumerable(); -// if (key instanceof JavaTransitiveInstancesKey) -// return false; -// else -// return true; - } - - @Override - public boolean canLeadOutOfScope(IInputKey key) { - ensureValidKey(key); - if (key instanceof EStructuralFeatureInstancesKey) { - EStructuralFeature feature = ((EStructuralFeatureInstancesKey) key).getEmfKey(); - if (feature instanceof EReference){ - return canLeadOutOfScope((EReference) feature); - } - } - return false; - } - - /** - * Tells whether the given reference may lead out of scope. - * @since 2.1 - */ - public boolean canLeadOutOfScope(EReference reference) { - // Is it possible that this edge is dangling, i.e. its target lies outside of the scope? - // Unless non-dangling is globally assumed, - // proxy-resolving references (incl. containment) might point to proxies and are thus considered unsafe. - // Additionally, if the scope is sub-resource (containment subtree of object), - // all non-containment edges are also unsafe. - // Note that in case of cross-resource containment, - // the scope includes the contained object even if it is in a foreign resource. - return (!assumeNonDangling) - && (reference.isResolveProxies() || (subResourceScopeSplit && !reference.isContainment())); - } - - @Override - public boolean isStateless(IInputKey key) { - ensureValidKey(key); - return key instanceof JavaTransitiveInstancesKey || key instanceof EClassUnscopedTransitiveInstancesKey; - } - - @Override - public Map, Set> getFunctionalDependencies(IInputKey key) { - ensureValidKey(key); - if (key instanceof EStructuralFeatureInstancesKey) { - EStructuralFeature feature = ((EStructuralFeatureInstancesKey) key).getEmfKey(); - final Map, Set> result = - new HashMap, Set>(); - if (isFeatureMultiplicityToOne(feature)) - result.put(Collections.singleton(0), Collections.singleton(1)); - if (isFeatureMultiplicityOneTo(feature)) - result.put(Collections.singleton(1), Collections.singleton(0)); - return result; - } else { - return Collections.emptyMap(); - } - } - - /** - * @since 2.1 - */ - public EClassTransitiveInstancesKey getSourceTypeKey(EStructuralFeatureInstancesKey key) { - return new EClassTransitiveInstancesKey(key.getEmfKey().getEContainingClass()); - } - /** - * @since 2.1 - */ - public IInputKey getTargetTypeKey(EStructuralFeatureInstancesKey key) { - EStructuralFeature feature = key.getEmfKey(); - if (feature instanceof EAttribute) { - return new EDataTypeInSlotsKey(((EAttribute) feature).getEAttributeType()); - } else if (feature instanceof EReference) { - EClass eReferenceType = ((EReference) feature).getEReferenceType(); - if (canLeadOutOfScope(key)) { - return new EClassUnscopedTransitiveInstancesKey(eReferenceType); - } else { - return new EClassTransitiveInstancesKey(eReferenceType); - } - } else throw new IllegalArgumentException(); - } - - @Override - public Collection getImplications(IInputKey implyingKey) { - ensureValidKey(implyingKey); - Collection result = new HashSet(); - - if (implyingKey instanceof EClassTransitiveInstancesKey) { - EClass eClass = ((EClassTransitiveInstancesKey) implyingKey).getEmfKey(); - - // direct eSuperClasses - EList directSuperTypes = eClass.getESuperTypes(); - if (!directSuperTypes.isEmpty()) { - for (EClass superType : directSuperTypes) { - final EClassTransitiveInstancesKey implied = new EClassTransitiveInstancesKey(superType); - result.add(new InputKeyImplication(implyingKey, implied, Arrays.asList(0))); - } - } else { - if (!EOBJECT_SCOPED_KEY.equals(implyingKey)) { - result.add(new InputKeyImplication(implyingKey, EOBJECT_SCOPED_KEY, Arrays.asList(0))); - } - } - // implies unscoped - if (UnscopedTypeSupport.EMIT_NEVER != emitUnscopedEClassTypes) - result.add(new InputKeyImplication(implyingKey, - new EClassUnscopedTransitiveInstancesKey(eClass), - Arrays.asList(0))); - } else if (implyingKey instanceof EClassUnscopedTransitiveInstancesKey) { - EClass eClass = ((EClassUnscopedTransitiveInstancesKey) implyingKey).getEmfKey(); - - // direct eSuperClasses - EList directSuperTypes = eClass.getESuperTypes(); - if (!directSuperTypes.isEmpty()) { - for (EClass superType : directSuperTypes) { - final EClassUnscopedTransitiveInstancesKey implied = new EClassUnscopedTransitiveInstancesKey( - superType); - result.add(new InputKeyImplication(implyingKey, implied, Arrays.asList(0))); - } - } else { - if (!EOBJECT_UNSCOPED_KEY.equals(implyingKey)) { - result.add(new InputKeyImplication(implyingKey, EOBJECT_UNSCOPED_KEY, Arrays.asList(0))); - } - } - - } else if (implyingKey instanceof JavaTransitiveInstancesKey) { - Class instanceClass = ((JavaTransitiveInstancesKey) implyingKey).getInstanceClass(); - if (instanceClass != null) { // resolution successful - // direct Java superClass - Class superclass = instanceClass.getSuperclass(); - if (superclass != null) { - JavaTransitiveInstancesKey impliedSuper = new JavaTransitiveInstancesKey(superclass); - result.add(new InputKeyImplication(implyingKey, impliedSuper, Arrays.asList(0))); - } - - // direct Java superInterfaces - for (Class superInterface : instanceClass.getInterfaces()) { - if (superInterface != null) { - JavaTransitiveInstancesKey impliedInterface = new JavaTransitiveInstancesKey(superInterface); - result.add(new InputKeyImplication(implyingKey, impliedInterface, Arrays.asList(0))); - } - } - } - - } else if (implyingKey instanceof EStructuralFeatureInstancesKey) { - EStructuralFeature feature = ((EStructuralFeatureInstancesKey) implyingKey).getEmfKey(); - - // source and target type - final EClass sourceType = featureSourceType(feature); - final EClassTransitiveInstancesKey impliedSource = new EClassTransitiveInstancesKey(sourceType); - final EClassifier targetType = featureTargetType(feature); - final IInputKey impliedTarget; - if (feature instanceof EReference) { - EReference reference = (EReference) feature; - - if (!canLeadOutOfScope(reference)) { - impliedTarget = new EClassTransitiveInstancesKey((EClass) targetType); - } else { - impliedTarget = (UnscopedTypeSupport.EMIT_NEVER != emitUnscopedEClassTypes) ? - new EClassUnscopedTransitiveInstancesKey((EClass) targetType) - : null; - } - } else { // EDatatype - impliedTarget = new EDataTypeInSlotsKey((EDataType) targetType); - } - - result.add(new InputKeyImplication(implyingKey, impliedSource, Arrays.asList(0))); - if (impliedTarget != null) - result.add(new InputKeyImplication(implyingKey, impliedTarget, Arrays.asList(1))); - - // opposite - EReference opposite = featureOpposite(feature); - if (opposite != null && !canLeadOutOfScope((EReference) feature)) { - EStructuralFeatureInstancesKey impliedOpposite = new EStructuralFeatureInstancesKey(opposite); - result.add(new InputKeyImplication(implyingKey, impliedOpposite, Arrays.asList(1, 0))); - } - - // containment - // TODO - } else if (implyingKey instanceof EDataTypeInSlotsKey) { - EDataType dataType = ((EDataTypeInSlotsKey) implyingKey).getEmfKey(); - - // instance class of datatype - // TODO this can have a generation gap! (could be some dynamic EMF impl or whatever) - Class instanceClass = dataType.getInstanceClass(); - if (instanceClass != null) { - JavaTransitiveInstancesKey implied = new JavaTransitiveInstancesKey(instanceClass); - result.add(new InputKeyImplication(implyingKey, implied, Arrays.asList(0))); - } - } else { - illegalInputKey(implyingKey); - } - - return result; - } - - @Override - public Map> getConditionalImplications(IInputKey implyingKey) { - ensureValidKey(implyingKey); - if (implyingKey instanceof EClassUnscopedTransitiveInstancesKey) { - EClass emfKey = ((EClassUnscopedTransitiveInstancesKey) implyingKey).getEmfKey(); - - Map> result = new HashMap<>(); - result.put( - new InputKeyImplication(implyingKey, EOBJECT_SCOPED_KEY, Arrays.asList(0)), - new HashSet<>(Arrays.asList(new InputKeyImplication(implyingKey, new EClassTransitiveInstancesKey(emfKey), Arrays.asList(0)))) - ); - return result; - } else return super.getConditionalImplications(implyingKey); - } - - @Override - public Collection getWeakenedAlternatives(IInputKey implyingKey) { - ensureValidKey(implyingKey); - if (UnscopedTypeSupport.EMIT_ALWAYS == emitUnscopedEClassTypes && implyingKey instanceof EClassTransitiveInstancesKey) { - EClass emfKey = ((EClassTransitiveInstancesKey) implyingKey).getEmfKey(); - - Collection result = new HashSet(); - result.add( - // in some cases, filtering by the the unscoped key may be sufficient - new InputKeyImplication(implyingKey, new EClassUnscopedTransitiveInstancesKey(emfKey), Arrays.asList(0)) - ); - return result; - } else return super.getWeakenedAlternatives(implyingKey); - } - - public void ensureValidKey(IInputKey key) { - if (! (key instanceof BaseEMFTypeKey) && ! (key instanceof JavaTransitiveInstancesKey)) - illegalInputKey(key); - } - - public void illegalInputKey(IInputKey key) { - throw new IllegalArgumentException("The input key " + key + " is not a valid EMF input key."); - } - - public boolean isFeatureMultiplicityToOne(EStructuralFeature feature) { - return !feature.isMany(); - } - - public boolean isFeatureMultiplicityOneTo(EStructuralFeature typeObject) { - if (typeObject instanceof EReference) { - final EReference feature = (EReference)typeObject; - final EReference eOpposite = feature.getEOpposite(); - return feature.isContainment() || (eOpposite != null && !eOpposite.isMany()); - } else return false; - } - - public EClass featureSourceType(EStructuralFeature feature) { - return feature.getEContainingClass(); - } - public EClassifier featureTargetType(EStructuralFeature typeObject) { - if (typeObject instanceof EAttribute) { - EAttribute attribute = (EAttribute) typeObject; - return attribute.getEAttributeType(); - } else if (typeObject instanceof EReference) { - EReference reference = (EReference) typeObject; - return reference.getEReferenceType(); - } else - throw new IllegalArgumentException("typeObject has invalid type " + typeObject.getClass().getName()); - } - public EReference featureOpposite(EStructuralFeature typeObject) { - if (typeObject instanceof EReference) { - EReference reference = (EReference) typeObject; - return reference.getEOpposite(); - } else return null; - } - - @Override - public Comparator getSuggestedEliminationOrdering() { - return SUGGESTED_ELIMINATION_ORDERING; - } - - private static final Comparator SUGGESTED_ELIMINATION_ORDERING = new Comparator() { - @Override - public int compare(IInputKey o1, IInputKey o2) { - if (o1 instanceof EClassTransitiveInstancesKey && o2 instanceof EClassTransitiveInstancesKey) { - // common EClass types with many instances should be eliminated before rare types - return getRarity((EClassTransitiveInstancesKey)o1) - getRarity((EClassTransitiveInstancesKey)o2); - } else { - return getKeyTypeEliminationSequence(o1) - getKeyTypeEliminationSequence(o2); - } - } - - // The more supertypes there are, the more specialized the type - // the more specialized the type, the rarer instances are expected to be found - private int getRarity(EClassTransitiveInstancesKey key) { - return key.getEmfKey().getEAllSuperTypes().size() + (EOBJECT_SCOPED_KEY.equals(key) ? 0 : 1); - } - - // Scoped EClass transitive instance keys are attempted to be eliminated before all else - // so that e.g. their unscoped version can eliminate them is variable is known to be scoped - private int getKeyTypeEliminationSequence(IInputKey o1) { - return (o1 instanceof EClassTransitiveInstancesKey) ? -1 : 0; - } - }; - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFQueryRuntimeContext.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFQueryRuntimeContext.java deleted file mode 100644 index 7809cd24..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFQueryRuntimeContext.java +++ /dev/null @@ -1,839 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Bergmann Gabor, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.emf; - -import java.lang.reflect.InvocationTargetException; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.Callable; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.apache.log4j.Logger; -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EDataType; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.base.api.DataTypeListener; -import tools.refinery.viatra.runtime.base.api.FeatureListener; -import tools.refinery.viatra.runtime.base.api.IndexingLevel; -import tools.refinery.viatra.runtime.base.api.InstanceListener; -import tools.refinery.viatra.runtime.base.api.NavigationHelper; -import tools.refinery.viatra.runtime.emf.types.EClassTransitiveInstancesKey; -import tools.refinery.viatra.runtime.emf.types.EClassUnscopedTransitiveInstancesKey; -import tools.refinery.viatra.runtime.emf.types.EDataTypeInSlotsKey; -import tools.refinery.viatra.runtime.emf.types.EStructuralFeatureInstancesKey; -import tools.refinery.viatra.runtime.matchers.context.AbstractQueryRuntimeContext; -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext; -import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContextListener; -import tools.refinery.viatra.runtime.matchers.context.IndexingService; -import tools.refinery.viatra.runtime.matchers.context.common.JavaTransitiveInstancesKey; -import tools.refinery.viatra.runtime.matchers.tuple.ITuple; -import tools.refinery.viatra.runtime.matchers.tuple.Tuple; -import tools.refinery.viatra.runtime.matchers.tuple.TupleMask; -import tools.refinery.viatra.runtime.matchers.tuple.Tuples; -import tools.refinery.viatra.runtime.matchers.util.Accuracy; - -/** - * The EMF-based runtime query context, backed by an IQBase NavigationHelper. - * - * @author Bergmann Gabor - * - *

TODO: {@link #ensureIndexed(EClass)} may be inefficient if supertype already cached. - * @since 1.4 - */ -public class EMFQueryRuntimeContext extends AbstractQueryRuntimeContext { - protected final NavigationHelper baseIndex; - //private BaseIndexListener listener; - - protected final Map> indexedClasses = new HashMap<>(); - protected final Map> indexedDataTypes = new HashMap<>(); - protected final Map> indexedFeatures = new HashMap<>(); - - protected final EMFQueryMetaContext metaContext; - - protected Logger logger; - - private EMFScope emfScope; - - public EMFQueryRuntimeContext(NavigationHelper baseIndex, Logger logger, EMFScope emfScope) { - this.baseIndex = baseIndex; - this.logger = logger; - this.metaContext = new EMFQueryMetaContext(emfScope); - this.emfScope = emfScope; - } - - public EMFScope getEmfScope() { - return emfScope; - } - - /** - * Utility method to add an indexing service to a given key. Returns true if the requested service was - * not present before this call. - * @param map - * @param key - * @param service - * @return - */ - private static boolean addIndexingService(Map> map, K key, IndexingService service){ - EnumSet current = map.get(key); - if (current == null){ - current = EnumSet.of(service); - map.put(key, current); - return true; - }else{ - return current.add(service); - } - } - - public void dispose() { - //baseIndex.removeFeatureListener(indexedFeatures, listener); - indexedFeatures.clear(); - //baseIndex.removeInstanceListener(indexedClasses, listener); - indexedClasses.clear(); - //baseIndex.removeDataTypeListener(indexedDataTypes, listener); - indexedDataTypes.clear(); - - // No need to remove listeners, as NavHelper will be disposed imminently. - } - - @Override - public V coalesceTraversals(Callable callable) throws InvocationTargetException { - return baseIndex.coalesceTraversals(callable); - } - - @Override - public boolean isCoalescing() { - return baseIndex.isCoalescing(); - } - - @Override - public IQueryMetaContext getMetaContext() { - return metaContext; - } - - @Override - public void ensureIndexed(IInputKey key, IndexingService service) { - ensureEnumerableKey(key); - if (key instanceof EClassTransitiveInstancesKey) { - EClass eClass = ((EClassTransitiveInstancesKey) key).getEmfKey(); - ensureIndexed(eClass, service); - } else if (key instanceof EDataTypeInSlotsKey) { - EDataType dataType = ((EDataTypeInSlotsKey) key).getEmfKey(); - ensureIndexed(dataType, service); - } else if (key instanceof EStructuralFeatureInstancesKey) { - EStructuralFeature feature = ((EStructuralFeatureInstancesKey) key).getEmfKey(); - ensureIndexed(feature, service); - } else { - illegalInputKey(key); - } - } - - /** - * Retrieve the current registered indexing services for the given key. May not return null, - * returns an empty set if no indexing is registered. - * - * @since 1.4 - */ - protected EnumSet getCurrentIndexingServiceFor(IInputKey key){ - ensureEnumerableKey(key); - if (key instanceof EClassTransitiveInstancesKey) { - EClass eClass = ((EClassTransitiveInstancesKey) key).getEmfKey(); - EnumSet is = indexedClasses.get(eClass); - return is == null ? EnumSet.noneOf(IndexingService.class) : is; - } else if (key instanceof EDataTypeInSlotsKey) { - EDataType dataType = ((EDataTypeInSlotsKey) key).getEmfKey(); - EnumSet is = indexedDataTypes.get(dataType); - return is == null ? EnumSet.noneOf(IndexingService.class) : is; - } else if (key instanceof EStructuralFeatureInstancesKey) { - EStructuralFeature feature = ((EStructuralFeatureInstancesKey) key).getEmfKey(); - EnumSet is = indexedFeatures.get(feature); - return is == null ? EnumSet.noneOf(IndexingService.class) : is; - } else { - illegalInputKey(key); - return EnumSet.noneOf(IndexingService.class); - } - } - - @Override - public boolean isIndexed(IInputKey key, IndexingService service) { - return getCurrentIndexingServiceFor(key).contains(service); - } - - @Override - public boolean containsTuple(IInputKey key, ITuple seed) { - ensureValidKey(key); - if (key instanceof JavaTransitiveInstancesKey) { - Class instanceClass = forceGetWrapperInstanceClass((JavaTransitiveInstancesKey) key); - return instanceClass != null && instanceClass.isInstance(seed.get(0)); - } else if (key instanceof EClassUnscopedTransitiveInstancesKey) { - EClass emfKey = ((EClassUnscopedTransitiveInstancesKey) key).getEmfKey(); - Object candidateInstance = seed.get(0); - return candidateInstance instanceof EObject - && baseIndex.isInstanceOfUnscoped((EObject) candidateInstance, emfKey); - } else { - ensureIndexed(key, IndexingService.INSTANCES); - if (key instanceof EClassTransitiveInstancesKey) { - EClass eClass = ((EClassTransitiveInstancesKey) key).getEmfKey(); - // instance check not enough to satisfy scoping, must lookup from index - Object candidateInstance = seed.get(0); - return candidateInstance instanceof EObject - && baseIndex.isInstanceOfScoped((EObject) candidateInstance, eClass); - } else if (key instanceof EDataTypeInSlotsKey) { - EDataType dataType = ((EDataTypeInSlotsKey) key).getEmfKey(); - return baseIndex.isInstanceOfDatatype(seed.get(0), dataType); - } else if (key instanceof EStructuralFeatureInstancesKey) { - EStructuralFeature feature = ((EStructuralFeatureInstancesKey) key).getEmfKey(); - Object sourceCandidate = seed.get(0); - return sourceCandidate instanceof EObject - && baseIndex.isFeatureInstance((EObject) sourceCandidate, seed.get(1), feature); - } else { - illegalInputKey(key); - return false; - } - } - } - - private Class forceGetWrapperInstanceClass(JavaTransitiveInstancesKey key) { - Class instanceClass; - try { - instanceClass = key.forceGetWrapperInstanceClass(); - } catch (ClassNotFoundException e) { - logger.error("Could not load instance class for type constraint " + key.getWrappedKey(), e); - instanceClass = null; - } - return instanceClass; - } - - @Override - public Iterable enumerateTuples(IInputKey key, TupleMask seedMask, ITuple seed) { - ensureIndexed(key, IndexingService.INSTANCES); - final Collection result = new HashSet(); - - if (key instanceof EClassTransitiveInstancesKey) { - EClass eClass = ((EClassTransitiveInstancesKey) key).getEmfKey(); - - if (seedMask.indices.length == 0) { // unseeded - return baseIndex.getAllInstances(eClass).stream().map(wrapUnary).collect(Collectors.toSet()); - } else { // fully seeded - Object seedInstance = seedMask.getValue(seed, 0); - if (containsTuple(key, seed)) - result.add(Tuples.staticArityFlatTupleOf(seedInstance)); - } - } else if (key instanceof EDataTypeInSlotsKey) { - EDataType dataType = ((EDataTypeInSlotsKey) key).getEmfKey(); - - if (seedMask.indices.length == 0) { // unseeded - return baseIndex.getDataTypeInstances(dataType).stream().map(wrapUnary).collect(Collectors.toSet()); - } else { // fully seeded - Object seedInstance = seedMask.getValue(seed, 0); - if (containsTuple(key, seed)) - result.add(Tuples.staticArityFlatTupleOf(seedInstance)); - } - } else if (key instanceof EStructuralFeatureInstancesKey) { - EStructuralFeature feature = ((EStructuralFeatureInstancesKey) key).getEmfKey(); - - boolean isSourceBound = false; - int sourceIndex = -1; - boolean isTargetBound = false; - int targetIndex = -1; - for (int i = 0; i < seedMask.getSize(); i++) { - int index = seedMask.indices[i]; - if (index == 0) { - isSourceBound = true; - sourceIndex = i; - } else if (index == 1) { - isTargetBound = true; - targetIndex = i; - } - } - - if (!isSourceBound && isTargetBound) { - final Object seedTarget = seed.get(targetIndex); - final Set results = baseIndex.findByFeatureValue(seedTarget, feature); - return results.stream().map(obj -> Tuples.staticArityFlatTupleOf(obj, seedTarget)).collect(Collectors.toSet()); - } else if (isSourceBound && isTargetBound) { // fully seeded - final Object seedSource = seed.get(sourceIndex); - final Object seedTarget = seed.get(targetIndex); - if (containsTuple(key, seed)) - result.add(Tuples.staticArityFlatTupleOf(seedSource, seedTarget)); - } else if (!isSourceBound && !isTargetBound) { // fully unseeded - baseIndex.processAllFeatureInstances(feature, (source, target) -> result.add(Tuples.staticArityFlatTupleOf(source, target))); - } else if (isSourceBound && !isTargetBound) { - final Object seedSource = seed.get(sourceIndex); - final Set results = baseIndex.getFeatureTargets((EObject) seedSource, feature); - return results.stream().map(obj -> Tuples.staticArityFlatTupleOf(seedSource, obj)).collect(Collectors.toSet()); - } - } else { - illegalInputKey(key); - } - - - return result; - } - - private static Function wrapUnary = Tuples::staticArityFlatTupleOf; - - @Override - public Iterable enumerateValues(IInputKey key, TupleMask seedMask, ITuple seed) { - ensureIndexed(key, IndexingService.INSTANCES); - - if (key instanceof EClassTransitiveInstancesKey) { - EClass eClass = ((EClassTransitiveInstancesKey) key).getEmfKey(); - - if (seedMask.indices.length == 0) { // unseeded - return baseIndex.getAllInstances(eClass); - } else { - // must be unseeded, this is enumerateValues after all! - illegalEnumerateValues(seed.toImmutable()); - } - } else if (key instanceof EDataTypeInSlotsKey) { - EDataType dataType = ((EDataTypeInSlotsKey) key).getEmfKey(); - - if (seedMask.indices.length == 0) { // unseeded - return baseIndex.getDataTypeInstances(dataType); - } else { - // must be unseeded, this is enumerateValues after all! - illegalEnumerateValues(seed.toImmutable()); - } - } else if (key instanceof EStructuralFeatureInstancesKey) { - EStructuralFeature feature = ((EStructuralFeatureInstancesKey) key).getEmfKey(); - - boolean isSourceBound = false; - int sourceIndex = -1; - boolean isTargetBound = false; - int targetIndex = -1; - for (int i = 0; i < seedMask.getSize(); i++) { - int index = seedMask.indices[i]; - if (index == 0) { - isSourceBound = true; - sourceIndex = i; - } else if (index == 1) { - isTargetBound = true; - targetIndex = i; - } - } - - if (!isSourceBound && isTargetBound) { - Object seedTarget = seed.get(targetIndex); - return baseIndex.findByFeatureValue(seedTarget, feature); - } else if (isSourceBound && !isTargetBound) { - Object seedSource = seed.get(sourceIndex); - return baseIndex.getFeatureTargets((EObject) seedSource, feature); - } else { - // must be singly unseeded, this is enumerateValues after all! - illegalEnumerateValues(seed.toImmutable()); - } - } else { - illegalInputKey(key); - } - return null; - } - - @Override - public int countTuples(IInputKey key, TupleMask seedMask, ITuple seed) { - ensureIndexed(key, IndexingService.STATISTICS); - - if (key instanceof EClassTransitiveInstancesKey) { - EClass eClass = ((EClassTransitiveInstancesKey) key).getEmfKey(); - - if (seedMask.indices.length == 0) { // unseeded - return baseIndex.countAllInstances(eClass); - } else { // fully seeded - return (containsTuple(key, seed)) ? 1 : 0; - } - } else if (key instanceof EDataTypeInSlotsKey) { - EDataType dataType = ((EDataTypeInSlotsKey) key).getEmfKey(); - - if (seedMask.indices.length == 0) { // unseeded - return baseIndex.countDataTypeInstances(dataType); - } else { // fully seeded - return (containsTuple(key, seed)) ? 1 : 0; - } - } else if (key instanceof EStructuralFeatureInstancesKey) { - EStructuralFeature feature = ((EStructuralFeatureInstancesKey) key).getEmfKey(); - - boolean isSourceBound = false; - int sourceIndex = -1; - boolean isTargetBound = false; - int targetIndex = -1; - for (int i = 0; i < seedMask.getSize(); i++) { - int index = seedMask.indices[i]; - if (index == 0) { - isSourceBound = true; - sourceIndex = i; - } else if (index == 1) { - isTargetBound = true; - targetIndex = i; - } - } - - if (!isSourceBound && isTargetBound) { - final Object seedTarget = seed.get(targetIndex); - return baseIndex.findByFeatureValue(seedTarget, feature).size(); - } else if (isSourceBound && isTargetBound) { // fully seeded - return (containsTuple(key, seed)) ? 1 : 0; - } else if (!isSourceBound && !isTargetBound) { // fully unseeded - return baseIndex.countFeatures(feature); - } else if (isSourceBound && !isTargetBound) { - final Object seedSource = seed.get(sourceIndex); - return baseIndex.countFeatureTargets((EObject) seedSource, feature); - } - } else { - illegalInputKey(key); - } - return 0; - } - - - /** - * @since 2.1 - */ - @Override - public Optional estimateCardinality(IInputKey key, TupleMask groupMask, Accuracy requiredAccuracy) { - - if (key instanceof EClassTransitiveInstancesKey) { - EClass eClass = ((EClassTransitiveInstancesKey) key).getEmfKey(); - - if (isIndexed(key, IndexingService.STATISTICS)) { // exact answer known - if (groupMask.indices.length == 0) { // empty projection - return (0 != baseIndex.countAllInstances(eClass)) ? Optional.of(1L) : Optional.of(0L); - } else { // unprojected - return Optional.of((long)baseIndex.countAllInstances(eClass)); - } - } else return Optional.empty(); // TODO use known supertype counts as upper, subtypes as lower bounds - - } else if (key instanceof EClassUnscopedTransitiveInstancesKey) { - EClass eClass = ((EClassUnscopedTransitiveInstancesKey) key).getEmfKey(); - - // can give only lower bound based on the scoped key - if (Accuracy.BEST_LOWER_BOUND.atLeastAsPreciseAs(requiredAccuracy)) { - return estimateCardinality(new EClassTransitiveInstancesKey(eClass), groupMask, requiredAccuracy); - } else return Optional.empty(); - - } else if (key instanceof EDataTypeInSlotsKey) { - EDataType dataType = ((EDataTypeInSlotsKey) key).getEmfKey(); - - if (isIndexed(key, IndexingService.STATISTICS)) { - if (groupMask.indices.length == 0) { // empty projection - return (0 != baseIndex.countDataTypeInstances(dataType)) ? Optional.of(1L) : Optional.of(0L); - } else { // unprojected - return Optional.of((long)baseIndex.countDataTypeInstances(dataType)); - } - } else return Optional.empty(); - - } else if (key instanceof EStructuralFeatureInstancesKey) { - EStructuralFeatureInstancesKey featureKey = (EStructuralFeatureInstancesKey) key; - EStructuralFeature feature = featureKey.getEmfKey(); - - - boolean isSourceSelected = false; - boolean isTargetSelected = false; - for (int i = 0; i < groupMask.getSize(); i++) { - int index = groupMask.indices[i]; - if (index == 0) { - isSourceSelected = true; - } else if (index == 1) { - isTargetSelected = true; - } - } - - Optional sourceTypeUpperEstimate = - estimateCardinality(metaContext.getSourceTypeKey(featureKey), - TupleMask.identity(1), Accuracy.BEST_UPPER_BOUND); - Optional targetTypeUpperEstimate = - estimateCardinality(metaContext.getTargetTypeKey(featureKey), - TupleMask.identity(1), Accuracy.BEST_UPPER_BOUND); - - if (!isSourceSelected && !isTargetSelected) { // empty projection - if (isIndexed(key, IndexingService.STATISTICS)) { // we have exact node counts - return (0 == baseIndex.countFeatures(feature)) ? Optional.of(0L) : Optional.of(1L); - } else { // we can still say 0 in a few cases - if (0 == sourceTypeUpperEstimate.orElse(-1L)) - return Optional.of(0L); - - if (0 == targetTypeUpperEstimate.orElse(-1L)) - return Optional.of(0L); - - return Optional.empty(); - } - - } else if (isSourceSelected && !isTargetSelected) { // count sources - if (isIndexed(key, IndexingService.INSTANCES)) { // we have instances, therefore feature end counts - return Optional.of((long)(baseIndex.getHoldersOfFeature(feature).size())); - } else if (metaContext.isFeatureMultiplicityToOne(feature) && - isIndexed(key, IndexingService.STATISTICS)) { // count of edges = count of sources due to func. dep. - return Optional.of((long)(baseIndex.countFeatures(feature))); - } else if (Accuracy.BEST_UPPER_BOUND.atLeastAsPreciseAs(requiredAccuracy)) { - // upper bound by source type - Optional estimate = sourceTypeUpperEstimate; - // total edge counts are another upper bound (even if instances are unindexed) - if (isIndexed(key, IndexingService.STATISTICS)) { - estimate = Optional.of(Math.min( - baseIndex.countFeatures(feature), - estimate.orElse(Long.MAX_VALUE))); - } - return estimate; - } else return Optional.empty(); - - } else if (!isSourceSelected /*&& isTargetSelected*/) { // count targets - if (isIndexed(key, IndexingService.INSTANCES)) { // we have instances, therefore feature end counts - return Optional.of((long)(baseIndex.getValuesOfFeature(feature).size())); - } else if (metaContext.isFeatureMultiplicityOneTo(feature) && - isIndexed(key, IndexingService.STATISTICS)) { // count of edges = count of targets due to func. dep. - return Optional.of((long)(baseIndex.countFeatures(feature))); - } else if (Accuracy.BEST_UPPER_BOUND.atLeastAsPreciseAs(requiredAccuracy)) { // upper bound by target type - // upper bound by target type - Optional estimate = targetTypeUpperEstimate; - // total edge counts are another upper bound (even if instances are unindexed) - if (isIndexed(key, IndexingService.STATISTICS)) { - estimate = Optional.of(Math.min( - baseIndex.countFeatures(feature), - estimate.orElse(Long.MAX_VALUE))); - } - return estimate; - } else return Optional.empty(); - - } else { // (isSourceSelected && isTargetSelected) // count edges - if (isIndexed(key, IndexingService.STATISTICS)) { // we have exact edge counts - return Optional.of((long)baseIndex.countFeatures(feature)); - } else if (Accuracy.BEST_UPPER_BOUND.atLeastAsPreciseAs(requiredAccuracy)) { // overestimates may still be available - Optional estimate = // trivial upper bound: product of source & target type sizes (if available) - (sourceTypeUpperEstimate.isPresent() && targetTypeUpperEstimate.isPresent()) ? - Optional.of( - ((long)sourceTypeUpperEstimate.get()) * targetTypeUpperEstimate.get() - ) : Optional.empty(); - - if (metaContext.isFeatureMultiplicityToOne(feature) && sourceTypeUpperEstimate.isPresent()) { - // upper bounded by source type due to func. dep. - estimate = Optional.of(Math.min( - sourceTypeUpperEstimate.get(), - estimate.orElse(Long.MAX_VALUE))); - } - if (metaContext.isFeatureMultiplicityOneTo(feature) && targetTypeUpperEstimate.isPresent()) { - // upper bounded by target type due to func. dep. - estimate = Optional.of(Math.min( - targetTypeUpperEstimate.get(), - estimate.orElse(Long.MAX_VALUE))); - } - - return estimate; - } else return Optional.empty(); - } - - } else { - return Optional.empty(); - } - } - - /** - * @since 2.1 - */ - @Override - public Optional estimateAverageBucketSize(IInputKey key, TupleMask groupMask, Accuracy requiredAccuracy) { - // smart handling of special cases - if (key instanceof EStructuralFeatureInstancesKey) { - EStructuralFeatureInstancesKey featureKey = (EStructuralFeatureInstancesKey) key; - EStructuralFeature feature = featureKey.getEmfKey(); - - // special treatment for edge navigation - if (1 == groupMask.getSize()) { - if (0 == groupMask.indices[0] && metaContext.isFeatureMultiplicityToOne(feature)) { // count targets per source - return Optional.of(1.0); - } else if (1 == groupMask.indices[0] && metaContext.isFeatureMultiplicityOneTo(feature)) { // count sources per target - return Optional.of(1.0); - } - } - } - - // keep the default behaviour - return super.estimateAverageBucketSize(key, groupMask, requiredAccuracy); - } - - - public void ensureEnumerableKey(IInputKey key) { - ensureValidKey(key); - if (! metaContext.isEnumerable(key)) - throw new IllegalArgumentException("Key is not enumerable: " + key); - - } - - public void ensureValidKey(IInputKey key) { - metaContext.ensureValidKey(key); - } - public void illegalInputKey(IInputKey key) { - metaContext.illegalInputKey(key); - } - public void illegalEnumerateValues(Tuple seed) { - throw new IllegalArgumentException("Must have exactly one unseeded element in enumerateValues() invocation, received instead: " + seed); - } - - /** - * @since 1.4 - */ - public void ensureIndexed(EClass eClass, IndexingService service) { - if (addIndexingService(indexedClasses, eClass, service)) { - final Set newClasses = Collections.singleton(eClass); - IndexingLevel level = IndexingLevel.toLevel(service); - if (!baseIndex.getIndexingLevel(eClass).providesLevel(level)) { - baseIndex.registerEClasses(newClasses, level); - } - //baseIndex.addInstanceListener(newClasses, listener); - } - } - - /** - * @since 1.4 - */ - public void ensureIndexed(EDataType eDataType, IndexingService service) { - if (addIndexingService(indexedDataTypes, eDataType, service)) { - final Set newDataTypes = Collections.singleton(eDataType); - IndexingLevel level = IndexingLevel.toLevel(service); - if (!baseIndex.getIndexingLevel(eDataType).providesLevel(level)) { - baseIndex.registerEDataTypes(newDataTypes, level); - } - //baseIndex.addDataTypeListener(newDataTypes, listener); - } - } - - /** - * @since 1.4 - */ - public void ensureIndexed(EStructuralFeature feature, IndexingService service) { - if (addIndexingService(indexedFeatures, feature, service)) { - final Set newFeatures = Collections.singleton(feature); - IndexingLevel level = IndexingLevel.toLevel(service); - if (!baseIndex.getIndexingLevel(feature).providesLevel(level)) { - baseIndex.registerEStructuralFeatures(newFeatures, level); - } - //baseIndex.addFeatureListener(newFeatures, listener); - } - } - - - - // UPDATE HANDLING SECTION - - /** - * Abstract internal listener wrapper for a {@link IQueryRuntimeContextListener}. - * Due to the overridden equals/hashCode(), it is safe to create a new instance for the same listener. - * - * @author Bergmann Gabor - */ - private abstract static class ListenerAdapter { - IQueryRuntimeContextListener listener; - Tuple seed; - /** - * @param listener - * @param seed must be non-null - */ - public ListenerAdapter(IQueryRuntimeContextListener listener, Object... seed) { - this.listener = listener; - this.seed = Tuples.flatTupleOf(seed); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((listener == null) ? 0 : listener.hashCode()); - result = prime * result + ((seed == null) ? 0 : seed.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (!(obj.getClass().equals(this.getClass()))) - return false; - ListenerAdapter other = (ListenerAdapter) obj; - if (listener == null) { - if (other.listener != null) - return false; - } else if (!listener.equals(other.listener)) - return false; - if (seed == null) { - if (other.seed != null) - return false; - } else if (!seed.equals(other.seed)) - return false; - return true; - } - - - @Override - public String toString() { - return "Wrapped#" + listener; - } - - - } - private static class EClassTransitiveInstancesAdapter extends ListenerAdapter implements InstanceListener { - private Object seedInstance; - public EClassTransitiveInstancesAdapter(IQueryRuntimeContextListener listener, Object seedInstance) { - super(listener, seedInstance); - this.seedInstance = seedInstance; - } - @Override - public void instanceInserted(EClass clazz, EObject instance) { - if (seedInstance != null && !seedInstance.equals(instance)) return; - listener.update(new EClassTransitiveInstancesKey(clazz), - Tuples.staticArityFlatTupleOf(instance), true); - } - @Override - public void instanceDeleted(EClass clazz, EObject instance) { - if (seedInstance != null && !seedInstance.equals(instance)) return; - listener.update(new EClassTransitiveInstancesKey(clazz), - Tuples.staticArityFlatTupleOf(instance), false); - } - } - private static class EDataTypeInSlotsAdapter extends ListenerAdapter implements DataTypeListener { - private Object seedValue; - public EDataTypeInSlotsAdapter(IQueryRuntimeContextListener listener, Object seedValue) { - super(listener, seedValue); - this.seedValue = seedValue; - } - @Override - public void dataTypeInstanceInserted(EDataType type, Object instance, - boolean firstOccurrence) { - if (firstOccurrence) { - if (seedValue != null && !seedValue.equals(instance)) return; - listener.update(new EDataTypeInSlotsKey(type), - Tuples.staticArityFlatTupleOf(instance), true); - } - } - @Override - public void dataTypeInstanceDeleted(EDataType type, Object instance, - boolean lastOccurrence) { - if (lastOccurrence) { - if (seedValue != null && !seedValue.equals(instance)) return; - listener.update(new EDataTypeInSlotsKey(type), - Tuples.staticArityFlatTupleOf(instance), false); - } - } - } - private static class EStructuralFeatureInstancesKeyAdapter extends ListenerAdapter implements FeatureListener { - private Object seedHost; - private Object seedValue; - public EStructuralFeatureInstancesKeyAdapter(IQueryRuntimeContextListener listener, Object seedHost, Object seedValue) { - super(listener, seedHost, seedValue); - this.seedHost = seedHost; - this.seedValue = seedValue; - } - @Override - public void featureInserted(EObject host, EStructuralFeature feature, - Object value) { - if (seedHost != null && !seedHost.equals(host)) return; - if (seedValue != null && !seedValue.equals(value)) return; - listener.update(new EStructuralFeatureInstancesKey(feature), - Tuples.staticArityFlatTupleOf(host, value), true); - } - @Override - public void featureDeleted(EObject host, EStructuralFeature feature, - Object value) { - if (seedHost != null && !seedHost.equals(host)) return; - if (seedValue != null && !seedValue.equals(value)) return; - listener.update(new EStructuralFeatureInstancesKey(feature), - Tuples.staticArityFlatTupleOf(host, value), false); - } - } - - @Override - public void addUpdateListener(IInputKey key, Tuple seed /* TODO ignored */, IQueryRuntimeContextListener listener) { - // stateless, so NOP - if (key instanceof JavaTransitiveInstancesKey) return; - - ensureIndexed(key, IndexingService.INSTANCES); - if (key instanceof EClassTransitiveInstancesKey) { - EClass eClass = ((EClassTransitiveInstancesKey) key).getEmfKey(); - baseIndex.addInstanceListener(Collections.singleton(eClass), - new EClassTransitiveInstancesAdapter(listener, seed.get(0))); - } else if (key instanceof EDataTypeInSlotsKey) { - EDataType dataType = ((EDataTypeInSlotsKey) key).getEmfKey(); - baseIndex.addDataTypeListener(Collections.singleton(dataType), - new EDataTypeInSlotsAdapter(listener, seed.get(0))); - } else if (key instanceof EStructuralFeatureInstancesKey) { - EStructuralFeature feature = ((EStructuralFeatureInstancesKey) key).getEmfKey(); - baseIndex.addFeatureListener(Collections.singleton(feature), - new EStructuralFeatureInstancesKeyAdapter(listener, seed.get(0), seed.get(1))); - } else { - illegalInputKey(key); - } - } - @Override - public void removeUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) { - // stateless, so NOP - if (key instanceof JavaTransitiveInstancesKey) return; - - ensureIndexed(key, IndexingService.INSTANCES); - if (key instanceof EClassTransitiveInstancesKey) { - EClass eClass = ((EClassTransitiveInstancesKey) key).getEmfKey(); - baseIndex.removeInstanceListener(Collections.singleton(eClass), - new EClassTransitiveInstancesAdapter(listener, seed.get(0))); - } else if (key instanceof EDataTypeInSlotsKey) { - EDataType dataType = ((EDataTypeInSlotsKey) key).getEmfKey(); - baseIndex.removeDataTypeListener(Collections.singleton(dataType), - new EDataTypeInSlotsAdapter(listener, seed.get(0))); - } else if (key instanceof EStructuralFeatureInstancesKey) { - EStructuralFeature feature = ((EStructuralFeatureInstancesKey) key).getEmfKey(); - baseIndex.removeFeatureListener(Collections.singleton(feature), - new EStructuralFeatureInstancesKeyAdapter(listener, seed.get(0), seed.get(1))); - } else { - illegalInputKey(key); - } - } - - // TODO wrap / unwrap enum literals - // TODO use this in all other public methods (maybe wrap & delegate?) - - @Override - public Object unwrapElement(Object internalElement) { - return internalElement; - } - @Override - public Tuple unwrapTuple(Tuple internalElements) { - return internalElements; - } - @Override - public Object wrapElement(Object externalElement) { - return externalElement; - } - @Override - public Tuple wrapTuple(Tuple externalElements) { - return externalElements; - } - - /** - * @since 1.4 - */ - @Override - public void ensureWildcardIndexing(IndexingService service) { - baseIndex.setWildcardLevel(IndexingLevel.toLevel(service)); - } - - /** - * @since 1.4 - */ - @Override - public void executeAfterTraversal(Runnable runnable) throws InvocationTargetException { - baseIndex.executeAfterTraversal(runnable); - } -} - diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFScope.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFScope.java deleted file mode 100644 index dead9716..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/EMFScope.java +++ /dev/null @@ -1,199 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2014, Bergmann Gabor, Denes Harmath, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.emf; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -import org.apache.log4j.Logger; -import org.eclipse.emf.common.notify.Notifier; -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; -import tools.refinery.viatra.runtime.api.AdvancedViatraQueryEngine; -import tools.refinery.viatra.runtime.api.ViatraQueryEngine; -import tools.refinery.viatra.runtime.api.scope.IEngineContext; -import tools.refinery.viatra.runtime.api.scope.IIndexingErrorListener; -import tools.refinery.viatra.runtime.api.scope.QueryScope; -import tools.refinery.viatra.runtime.base.api.BaseIndexOptions; -import tools.refinery.viatra.runtime.base.api.NavigationHelper; -import tools.refinery.viatra.runtime.exception.ViatraQueryException; - -/** - * An {@link QueryScope} consisting of EMF objects contained in multiple {@link ResourceSet}s, a single {@link ResourceSet}, {@link Resource} or a containment subtree below a given {@link EObject}. - * - *

The scope is characterized by a root and some options (see {@link BaseIndexOptions}) such as dynamic EMF mode, subtree filtering etc. - *

- * The scope of pattern matching will be the given EMF model root(s) and below (see FAQ for more precise definition). - * - *

Note on cross-resource containment: in case of {@link EObject} scopes, cross-resource containments will be considered part of the scope. - * The same goes for {@link ResourceSet} scopes, provided that the resource of the contained element is successfully loaded into the resource set. - * In case of a {@link Resource} scope, containments pointing out from the resource will be excluded from the scope. - * Thus the boundaries of {@link EObject} scopes conform to the notion of EMF logical containment, while {@link Resource} and {@link ResourceSet} scopes adhere to persistence boundaries. - * - * @author Bergmann Gabor - * - */ -public class EMFScope extends QueryScope { - - private Set scopeRoots; - private BaseIndexOptions options; - - /** - * Creates an EMF scope at the given root, with default options (recommended for most users). - * @param scopeRoot the root of the EMF scope - * @throws ViatraQueryRuntimeException- if scopeRoot is not an EMF ResourceSet, Resource or EObject - */ - public EMFScope(Notifier scopeRoot) { - this(Collections.singleton(scopeRoot), new BaseIndexOptions()); - } - - /** - * Creates an EMF scope at the given root, with customizable options. - *

Most users should consider {@link #EMFScope(Notifier)} instead. - * @param scopeRoot the root of the EMF scope - * @param options the base index building settings - * @throws ViatraQueryRuntimeException if scopeRoot is not an EMF ResourceSet, Resource or EObject - */ - public EMFScope(Notifier scopeRoot, BaseIndexOptions options) { - this(Collections.singleton(scopeRoot), options); - } - - /** - * Creates an EMF scope at the given roots, with default options (recommended for most users). - * @param scopeRoots the roots of the EMF scope, must be {@link ResourceSet}s - * @throws ViatraQueryRuntimeException if not all scopeRoots are {@link ResourceSet}s - */ - public EMFScope(Set scopeRoots) { - this(scopeRoots, new BaseIndexOptions()); - } - - /** - * Creates an EMF scope at the given roots, with customizable options. - *

Most users should consider {@link #EMFScope(Set)} instead. - * @param scopeRoots the roots of the EMF scope, must be {@link ResourceSet}s - * @param options the base index building settings - * @throws ViatraQueryRuntimeException if not all scopeRoots are {@link ResourceSet}s - */ - public EMFScope(Set scopeRoots, BaseIndexOptions options) { - super(); - if (scopeRoots.isEmpty()) { - throw new IllegalArgumentException("No scope roots given"); - } else if (scopeRoots.size() == 1) { - checkScopeRoots(scopeRoots, EObject.class::isInstance, Resource.class::isInstance, ResourceSet.class::isInstance); - } else { - checkScopeRoots(scopeRoots, ResourceSet.class::isInstance); - } - this.scopeRoots = new HashSet<>(scopeRoots); - this.options = options.copy(); - } - - @SafeVarargs - private final void checkScopeRoots(Set scopeRoots, Predicate... predicates) { - for (Notifier scopeRoot : scopeRoots) { - // Creating compound predicate that checks the various branches of disjunction together - Predicate compoundPredicate = Arrays.stream(predicates).collect(Collectors.reducing(a -> true, a -> a, (a, b) -> a.or(b))); - if (!compoundPredicate.test(scopeRoot)) - throw new ViatraQueryException(ViatraQueryException.INVALID_EMFROOT - + (scopeRoot == null ? "(null)" : scopeRoot.getClass().getName()), - ViatraQueryException.INVALID_EMFROOT_SHORT); - } - } - - /** - * @return the scope roots ({@link ResourceSet}s) containing the model - */ - public Set getScopeRoots() { - return scopeRoots; - } - - /** - * @return the options - */ - public BaseIndexOptions getOptions() { - return options.copy(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((options == null) ? 0 : options.hashCode()); - result = prime * result - + ((scopeRoots == null) ? 0 : scopeRoots.hashCode()); - return result; - } - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (!(obj instanceof EMFScope)) - return false; - EMFScope other = (EMFScope) obj; - if (options == null) { - if (other.options != null) - return false; - } else if (!options.equals(other.options)) - return false; - if (scopeRoots == null) { - if (other.scopeRoots != null) - return false; - } else if (!scopeRoots.equals(other.scopeRoots)) - return false; - return true; - } - - - @Override - public String toString() { - return String.format("EMFScope(%s):%s", options, scopeRoots.stream().map(this::scopeRootString).collect(Collectors.joining(","))); - } - - private String scopeRootString(Notifier notifier) { - if (notifier instanceof Resource) { - Resource resource = (Resource) notifier; - return String.format("%s(%s)", resource.getClass(), resource.getURI()); - } else if (notifier instanceof ResourceSet) { - ResourceSet resourceSet = (ResourceSet) notifier; - return resourceSet.getResources().stream() - .map(Resource::getURI) - .map(URI::toString) - .collect(Collectors.joining(", ", resourceSet.getClass() + "(", ")")); - } else { - return notifier.toString(); - } - } - - @Override - protected IEngineContext createEngineContext(ViatraQueryEngine engine, IIndexingErrorListener errorListener, Logger logger) { - return new EMFEngineContext(this, engine, errorListener, logger); - } - - /** - * Provides access to the underlying EMF model index ({@link NavigationHelper}) from a VIATRA Query engine instantiated on an EMFScope - * - * @param engine an already existing VIATRA Query engine instantiated on an EMFScope - * @return the underlying EMF base index that indexes the contents of the EMF model - * @throws ViatraQueryRuntimeException if base index initialization fails - */ - public static NavigationHelper extractUnderlyingEMFIndex(ViatraQueryEngine engine) { - final QueryScope scope = engine.getScope(); - if (scope instanceof EMFScope) - return ((EMFBaseIndexWrapper)AdvancedViatraQueryEngine.from(engine).getBaseIndex()).getNavigationHelper(); - else throw new IllegalArgumentException("Cannot extract EMF base index from VIATRA Query engine instantiated on non-EMF scope " + scope); - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/helper/ViatraQueryRuntimeHelper.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/helper/ViatraQueryRuntimeHelper.java deleted file mode 100644 index 93ac97f2..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/helper/ViatraQueryRuntimeHelper.java +++ /dev/null @@ -1,161 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2014, Abel Hegedus, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.emf.helper; - -import java.util.function.Function; - -import org.eclipse.emf.ecore.EClassifier; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EPackage; -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.api.IPatternMatch; - -/** - * Helper functions for dealing with the EMF objects with VIATRA Queries. - * - * @author Abel Hegedus - * @since 0.9 - * - */ -public class ViatraQueryRuntimeHelper { - - private ViatraQueryRuntimeHelper() {/*Utility class constructor*/} - - private static final Function STRING_VALUE_TRANSFORMER = input -> (input == null) ? "(null)" : input.toString(); - - /** - * Gives a human-readable name of an EMF type. - */ - public static String prettyPrintEMFType(Object typeObject) { - if (typeObject == null) { - return "(null)"; - } else if (typeObject instanceof EClassifier) { - final EClassifier eClassifier = (EClassifier) typeObject; - final EPackage ePackage = eClassifier.getEPackage(); - final String nsURI = ePackage == null ? null : ePackage.getNsURI(); - final String typeName = eClassifier.getName(); - return "" + nsURI + "/" + typeName; - } else if (typeObject instanceof EStructuralFeature) { - final EStructuralFeature feature = (EStructuralFeature) typeObject; - return prettyPrintEMFType(feature.getEContainingClass()) + "." + feature.getName(); - } else - return typeObject.toString(); - } - - - /** - * Get the structural feature with the given name of the given object. - * - * @param o - * the object (must be an EObject) - * @param featureName - * the name of the feature - * @return the EStructuralFeature of the object or null if it can not be found - */ - public static EStructuralFeature getFeature(Object o, String featureName) { - if (o instanceof EObject) { - EStructuralFeature feature = ((EObject) o).eClass().getEStructuralFeature(featureName); - return feature; - } - return null; - } - - /** - * Returns the message for the given match using the given format. The format string can refer to the value of - * parameter A of the match with $A$ and even access features of A (if it's an EObject), e.g. $A.id$. - * - *

- * If the selected parameter does not exist, the string "[no such parameter]" is added - * - *

- * If no feature is defined, but A has a feature called "name", then its value is used. - * - *

- * If the selected feature does not exist, A.toString() is added. - * - *

- * If the selected feature is null, the string "null" is added. - * - * @param match - * cannot be null! - * @param messageFormat - * cannot be null! - */ - public static String getMessage(IPatternMatch match, String messageFormat) { - return getMessage(match, messageFormat, STRING_VALUE_TRANSFORMER); - } - - /** - * Returns the message for the given match using the given format while transforming values with the given function. - * The format string can refer to the value of parameter A of the match with $A$ and even access features of A (if - * it's an EObject), e.g. $A.id$. The function will be called to compute the final string representation of the - * values selected by the message format. - * - *

- * If the selected parameter does not exist, the string "[no such parameter]" is added - * - *

- * If no feature is defined, but A has a feature called "name", then its value is passed to the function. - * - *

- * If the selected feature does not exist, A is passed to the function. - * - *

- * If the selected feature is null, the string "null" is added. - * - * @param match - * cannot be null! - * @param messageFormat - * cannot be null! - * @param parameterValueTransformer - * cannot be null! - * @since 2.0 - */ - public static String getMessage(IPatternMatch match, String messageFormat, Function parameterValueTransformer) { - String[] tokens = messageFormat.split("\\$"); - StringBuilder newText = new StringBuilder(); - - for (int i = 0; i < tokens.length; i++) { - if (i % 2 == 0) { - newText.append(tokens[i]); - } else { - String[] objectTokens = tokens[i].split("\\."); - if (objectTokens.length > 0) { - Object o = null; - EStructuralFeature feature = null; - - if (objectTokens.length == 1) { - o = match.get(objectTokens[0]); - feature = getFeature(o, "name"); - } - if (objectTokens.length == 2) { - o = match.get(objectTokens[0]); - feature = getFeature(o, objectTokens[1]); - } - - if (o != null && feature != null) { - Object value = ((EObject) o).eGet(feature); - if (value != null) { - newText.append(parameterValueTransformer.apply(value)); - } else { - newText.append("null"); - } - } else if (o != null) { - newText.append(parameterValueTransformer.apply(o)); - } - } else { - newText.append("[no such parameter]"); - } - } - } - - return newText.toString(); - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/BaseEMFTypeKey.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/BaseEMFTypeKey.java deleted file mode 100644 index c5dfa966..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/BaseEMFTypeKey.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Bergmann Gabor, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.emf.types; - -import tools.refinery.viatra.runtime.matchers.context.common.BaseInputKeyWrapper; - -/** - * Base class for EMF Type keys. - * @author Bergmann Gabor - * - */ -public abstract class BaseEMFTypeKey extends BaseInputKeyWrapper { - - public BaseEMFTypeKey(EMFKey emfKey) { - super(emfKey); - } - - public EMFKey getEmfKey() { - return getWrappedKey(); - } - - @Override - public String toString() { - return this.getPrettyPrintableName(); - } - - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EClassExactInstancesKey.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EClassExactInstancesKey.java deleted file mode 100644 index dd10502d..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EClassExactInstancesKey.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.emf.types; - -import org.eclipse.emf.ecore.EClass; -import tools.refinery.viatra.runtime.emf.EMFScope; -import tools.refinery.viatra.runtime.emf.helper.ViatraQueryRuntimeHelper; - -/** - * Instance tuples are of form (x), where x is an eObject instance of the given eClass, but not one of its subclasses, within the scope. - *

This input key has the strict semantics that instances must be within the scope. - * - * @noreference This class is not intended to be referenced by clients. Not currently supported by {@link EMFScope}, for internal use only at the time - * - * @author Bergmann Gabor - * @since 2.1 - */ -public class EClassExactInstancesKey extends BaseEMFTypeKey { - - public EClassExactInstancesKey(EClass emfKey) { - super(emfKey); - } - - @Override - public String getPrettyPrintableName() { - return "(scoped,exact) "+ViatraQueryRuntimeHelper.prettyPrintEMFType(wrappedKey); - } - - @Override - public String getStringID() { - return "eClass(scoped,exact)#"+ ViatraQueryRuntimeHelper.prettyPrintEMFType(wrappedKey); - } - - @Override - public int getArity() { - return 1; - } - - @Override - public boolean isEnumerable() { - return true; - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EClassTransitiveInstancesKey.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EClassTransitiveInstancesKey.java deleted file mode 100644 index 4ca6b220..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EClassTransitiveInstancesKey.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Bergmann Gabor, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.emf.types; - -import org.eclipse.emf.ecore.EClass; -import tools.refinery.viatra.runtime.emf.EMFScope; -import tools.refinery.viatra.runtime.emf.helper.ViatraQueryRuntimeHelper; - -/** - * Instance tuples are of form (x), where x is an eObject instance of the given eClass or one of its subclasses within the scope. - *

As of version 1.6, this input key has the strict semantics that instances must be within the {@link EMFScope}. - * @author Bergmann Gabor - * - */ -public class EClassTransitiveInstancesKey extends BaseEMFTypeKey { - - public EClassTransitiveInstancesKey(EClass emfKey) { - super(emfKey); - } - - @Override - public String getPrettyPrintableName() { - return "(scoped) "+ViatraQueryRuntimeHelper.prettyPrintEMFType(wrappedKey); - } - - @Override - public String getStringID() { - return "eClass(scoped)#"+ ViatraQueryRuntimeHelper.prettyPrintEMFType(wrappedKey); - } - - @Override - public int getArity() { - return 1; - } - - @Override - public boolean isEnumerable() { - return true; - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EClassUnscopedTransitiveInstancesKey.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EClassUnscopedTransitiveInstancesKey.java deleted file mode 100644 index 11c5b235..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EClassUnscopedTransitiveInstancesKey.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2017, Gabor Bergmann, IncQueryLabs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.emf.types; - -import org.eclipse.emf.ecore.EClass; -import tools.refinery.viatra.runtime.emf.helper.ViatraQueryRuntimeHelper; - -/** - * Instance tuples are of form (x), where x is an eObject instance of the given eClass or one of its subclasses regardless whether it is within the scope. - * - * @author Bergmann Gabor - * @since 1.6 - */ -public class EClassUnscopedTransitiveInstancesKey extends BaseEMFTypeKey { - - public EClassUnscopedTransitiveInstancesKey(EClass emfKey) { - super(emfKey); - } - - @Override - public String getPrettyPrintableName() { - return "(unscoped) "+ViatraQueryRuntimeHelper.prettyPrintEMFType(wrappedKey); - } - - @Override - public String getStringID() { - return "eClass(unscoped)#"+ ViatraQueryRuntimeHelper.prettyPrintEMFType(wrappedKey); - } - - @Override - public int getArity() { - return 1; - } - - @Override - public boolean isEnumerable() { - return false; - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EDataTypeInSlotsKey.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EDataTypeInSlotsKey.java deleted file mode 100644 index a1cc4863..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EDataTypeInSlotsKey.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Bergmann Gabor, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.emf.types; - -import org.eclipse.emf.ecore.EDataType; -import tools.refinery.viatra.runtime.emf.helper.ViatraQueryRuntimeHelper; - -/** - * Instance tuples are of form (x), where x is an instance of the given eDataType residing at an attribute slot of an eObject in the model. - * @author Bergmann Gabor - * - */ -public class EDataTypeInSlotsKey extends BaseEMFTypeKey { - - /** - * @param emfKey - */ - public EDataTypeInSlotsKey(EDataType emfKey) { - super(emfKey); - } - - @Override - public String getPrettyPrintableName() { - return "(Attribute Slot Values: " + ViatraQueryRuntimeHelper.prettyPrintEMFType(wrappedKey) + ")"; - } - - @Override - public String getStringID() { - return "slotValue#" + ViatraQueryRuntimeHelper.prettyPrintEMFType(wrappedKey); - } - - @Override - public int getArity() { - return 1; - } - - @Override - public boolean isEnumerable() { - return true; - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EStructuralFeatureInstancesKey.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EStructuralFeatureInstancesKey.java deleted file mode 100644 index 357f5e7e..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/emf/types/EStructuralFeatureInstancesKey.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Bergmann Gabor, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.emf.types; - -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.emf.EMFScope; -import tools.refinery.viatra.runtime.emf.helper.ViatraQueryRuntimeHelper; - -/** - * Instance tuples are of form (x, y), where x is an eObject that has y as the value of the given feature (or one of the values in case of multi-valued). - * - *

As of version 1.6, this input key has the strict semantics that x must be within the {@link EMFScope}, scoping is not implied for y. - * @author Bergmann Gabor - * - */ -public class EStructuralFeatureInstancesKey extends BaseEMFTypeKey { - - public EStructuralFeatureInstancesKey(EStructuralFeature emfKey) { - super(emfKey); - } - - @Override - public String getPrettyPrintableName() { - return ViatraQueryRuntimeHelper.prettyPrintEMFType(wrappedKey); - } - - @Override - public String getStringID() { - return "feature#"+ getPrettyPrintableName(); - } - - @Override - public int getArity() { - return 2; - } - - @Override - public boolean isEnumerable() { - return true; - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/IQueryGroupProvider.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/IQueryGroupProvider.java deleted file mode 100644 index 45594b5b..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/IQueryGroupProvider.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.extensibility; - -import java.util.Set; - -import tools.refinery.viatra.runtime.api.IQueryGroup; -import tools.refinery.viatra.runtime.matchers.util.IProvider; - -/** - * Provider interface for {@link IQueryGroup} instances with added method for - * requesting the set of FQNs for the query specifications in the group. - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public interface IQueryGroupProvider extends IProvider { - - /** - * Note that the provider should load the query group class only if the FQNs can not be computed in other ways. - * - * @return the set of query specification FQNs in the group - */ - Set getQuerySpecificationFQNs(); - - /** - * Note that the provider should load the query group class only if the FQNs can not be computed in other ways. - * - * @return a set of providers for query specifications in the group - */ - Set getQuerySpecificationProviders(); - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/IQuerySpecificationProvider.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/IQuerySpecificationProvider.java deleted file mode 100644 index 3c9c235d..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/IQuerySpecificationProvider.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.extensibility; - -import tools.refinery.viatra.runtime.api.IQuerySpecification; -import tools.refinery.viatra.runtime.matchers.util.IProvider; - -/** - * Provider interface for {@link IQuerySpecification} instances with added method for - * requesting the FQN for the query specification. - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public interface IQuerySpecificationProvider extends IProvider> { - - /** - * Note that the provider will usually not load the query specification class to return the FQN. - * - * @return the fully qualified name of the provided query specification - */ - String getFullyQualifiedName(); - - /** - * Returns the name of project providing the specification (or null if not calculable) - */ - String getSourceProjectName(); - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/PQueryExtensionFactory.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/PQueryExtensionFactory.java deleted file mode 100644 index 91e087d7..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/PQueryExtensionFactory.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Zoltan Ujhelyi, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.extensibility; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import tools.refinery.viatra.runtime.api.IQuerySpecification; - -/** - * An extension factory to access PQuery instances from Query Specifications. - * - * @author Zoltan Ujhelyi - * - */ -public class PQueryExtensionFactory extends SingletonExtensionFactory { - - @Override - public Object create() throws CoreException { - final Object _spec = super.create(); - if (_spec instanceof IQuerySpecification) { - return ((IQuerySpecification) _spec).getInternalQueryRepresentation(); - } - throw new CoreException(new Status(IStatus.ERROR, getBundle().getSymbolicName(), "Cannot instantiate PQuery instance.")); - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/SingletonExtensionFactory.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/SingletonExtensionFactory.java deleted file mode 100644 index 29705968..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/SingletonExtensionFactory.java +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2014, Zoltan Ujhelyi, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.extensibility; - -import java.lang.reflect.Method; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExecutableExtension; -import org.eclipse.core.runtime.IExecutableExtensionFactory; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.osgi.framework.Bundle; - -/** - * Factory to register a static singleton instance in an extension point. - * - * @author Zoltan Ujhelyi - * - */ -public class SingletonExtensionFactory implements IExecutableExtension, IExecutableExtensionFactory { - - private String clazzName; - private Bundle bundle; - - protected Bundle getBundle() { - return bundle; - } - - @Override - public Object create() throws CoreException { - try { - final Class clazz = bundle.loadClass(clazzName); - Method method = clazz.getMethod("instance"); - return method.invoke(null); - } catch (Exception e) { - throw new CoreException(new Status(IStatus.ERROR, bundle.getSymbolicName(), "Error loading group " - + clazzName, e)); - } - } - - @Override - public void setInitializationData(IConfigurationElement config, String propertyName, Object data) - throws CoreException { - String id = config.getContributor().getName(); - bundle = Platform.getBundle(id); - if (data instanceof String) { - clazzName = (String) data; - } else { - throw new CoreException(new Status(IStatus.ERROR, bundle.getSymbolicName(), - "Unsupported extension initialization data: " + data)); - } - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/SingletonQueryGroupProvider.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/SingletonQueryGroupProvider.java deleted file mode 100644 index 758b51dd..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/SingletonQueryGroupProvider.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.extensibility; - -import java.util.Set; -import java.util.stream.Collectors; - -import tools.refinery.viatra.runtime.api.IQueryGroup; -import tools.refinery.viatra.runtime.api.IQuerySpecification; -import tools.refinery.viatra.runtime.matchers.util.SingletonInstanceProvider; - -/** - * Provider implementation for storing an existing query group instance. - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public class SingletonQueryGroupProvider extends SingletonInstanceProvider implements IQueryGroupProvider { - - /** - * @param instance the instance to wrap - */ - public SingletonQueryGroupProvider(IQueryGroup instance) { - super(instance); - } - - @Override - public Set getQuerySpecificationFQNs() { - return get().getSpecifications().stream().map(IQuerySpecification::getFullyQualifiedName) - .collect(Collectors.toSet()); - } - - @Override - public Set getQuerySpecificationProviders() { - return get().getSpecifications().stream().map(SingletonQuerySpecificationProvider::new) - .collect(Collectors.toSet()); - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/SingletonQuerySpecificationProvider.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/SingletonQuerySpecificationProvider.java deleted file mode 100644 index f8f3a741..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/SingletonQuerySpecificationProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.extensibility; - -import tools.refinery.viatra.runtime.api.IQuerySpecification; -import tools.refinery.viatra.runtime.matchers.util.SingletonInstanceProvider; - -/** - * Provider implementation for storing an existing query specification instance. - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public class SingletonQuerySpecificationProvider extends SingletonInstanceProvider> - implements IQuerySpecificationProvider { - - /** - * - * @param instance the instance to wrap - */ - public SingletonQuerySpecificationProvider(IQuerySpecification instance) { - super(instance); - } - - @Override - public String getFullyQualifiedName() { - return get().getFullyQualifiedName(); - } - - @Override - public String getSourceProjectName() { - return null; - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/ViatraQueryRuntimeConstants.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/ViatraQueryRuntimeConstants.java deleted file mode 100644 index 9b0850e4..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/extensibility/ViatraQueryRuntimeConstants.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Abel Hegedus, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.extensibility; - -/** - * Utility class for Viatra Query runtime constants, such as extension point identifiers. - * - * @author Abel Hegedus - * - */ -public final class ViatraQueryRuntimeConstants { - - private ViatraQueryRuntimeConstants() {/* Constructor hidden for utility class */} - - // Surrogate query extension - - public static final String SURROGATE_QUERY_EXTENSIONID = "tools.refinery.viatra.runtime.surrogatequeryemf"; - - - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/internal/ExtensionBasedSurrogateQueryLoader.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/internal/ExtensionBasedSurrogateQueryLoader.java deleted file mode 100644 index af7cdaf1..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/internal/ExtensionBasedSurrogateQueryLoader.java +++ /dev/null @@ -1,148 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2015, Abel Hegedus, Zoltan Ujhelyi, Istvan Rath and Daniel Varro - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.internal; - -import static tools.refinery.viatra.runtime.matchers.util.Preconditions.checkState; - -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import org.apache.log4j.Logger; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.Platform; -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EClassifier; -import org.eclipse.emf.ecore.EPackage; -import org.eclipse.emf.ecore.EStructuralFeature; -import tools.refinery.viatra.runtime.emf.types.EStructuralFeatureInstancesKey; -import tools.refinery.viatra.runtime.extensibility.ViatraQueryRuntimeConstants; -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.context.surrogate.SurrogateQueryRegistry; -import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery; -import tools.refinery.viatra.runtime.matchers.util.IProvider; - -/** - * @author Abel Hegedus - * - */ -public class ExtensionBasedSurrogateQueryLoader { - - private static final String DUPLICATE_SURROGATE_QUERY = "Duplicate surrogate query definition %s for feature %s of EClass %s in package %s (FQN in map %s, contributing plug-ins %s, plug-in %s)"; - - private Map contributingPluginOfFeatureMap = new HashMap<>(); - private Map contributedSurrogateQueries; - - private static final ExtensionBasedSurrogateQueryLoader INSTANCE = new ExtensionBasedSurrogateQueryLoader(); - - /** - * A provider implementation for PQuery instances based on extension elements. It is expected that the getter will only - * @author Zoltan Ujhelyi - * - */ - private static final class PQueryProvider implements IProvider { - - private final IConfigurationElement element; - private PQuery query; - - public PQueryProvider(IConfigurationElement element) { - this.element = element; - this.query = null; - } - - @Override - public PQuery get() { - try { - if (query == null) { - query = (PQuery) element.createExecutableExtension("surrogate-query"); - } - return query; - } catch (CoreException e) { - throw new IllegalArgumentException("Error initializing surrogate query", e); - } - } - } - - public static ExtensionBasedSurrogateQueryLoader instance() { - return INSTANCE; - } - - public void loadKnownSurrogateQueriesIntoRegistry() { - Map knownSurrogateQueryFQNs = getSurrogateQueryProviders(); - for (Entry entry : knownSurrogateQueryFQNs.entrySet()) { - final IInputKey inputKey = new EStructuralFeatureInstancesKey(entry.getKey()); - SurrogateQueryRegistry.instance().registerSurrogateQueryForFeature(inputKey, entry.getValue()); - } - } - - private Map getSurrogateQueryProviders() { - if(contributedSurrogateQueries != null) { - return contributedSurrogateQueries; - } - contributedSurrogateQueries = new HashMap<>(); - if (Platform.isRunning()) { - for (IConfigurationElement e : Platform.getExtensionRegistry().getConfigurationElementsFor(ViatraQueryRuntimeConstants.SURROGATE_QUERY_EXTENSIONID)) { - if (e.isValid()) { - processExtension(e); - } - } - } - return contributedSurrogateQueries; - } - - private void processExtension(IConfigurationElement el) { - - try { - String packageUri = el.getAttribute("package-nsUri"); - String className = el.getAttribute("class-name"); - String featureName = el.getAttribute("feature-name"); - String queryFqn = el.getAttribute("query-fqn"); - if (queryFqn == null) { - queryFqn = ""; - } - PQueryProvider surrogateQueryProvider = new PQueryProvider(el); - - String contributorName = el.getContributor().getName(); - StringBuilder featureIdBuilder = new StringBuilder(); - checkState(packageUri != null, "Package NsURI cannot be null in extension"); - checkState(className != null, "Class name cannot be null in extension"); - checkState(featureName != null, "Feature name cannot be null in extension"); - - EPackage pckg = EPackage.Registry.INSTANCE.getEPackage(packageUri); - featureIdBuilder.append(packageUri); - checkState(pckg != null, "Package %s not found! (plug-in %s)", packageUri, contributorName); - - EClassifier clsr = pckg.getEClassifier(className); - featureIdBuilder.append("##").append(className); - checkState(clsr instanceof EClass, "EClassifier %s does not exist in package %s! (plug-in %s)", className, packageUri, contributorName); - - EClass cls = (EClass) clsr; - EStructuralFeature feature = cls.getEStructuralFeature(featureName); - featureIdBuilder.append("##").append(featureName); - checkState(feature != null, "Feature %s of EClass %s in package %s not found! (plug-in %s)", featureName, className, packageUri, contributorName); - - PQueryProvider fqnInMap = contributedSurrogateQueries.get(feature); - if(fqnInMap != null) { - String duplicateSurrogateFormatString = DUPLICATE_SURROGATE_QUERY; - Collection contributorPlugins = Arrays.asList(contributorName, contributingPluginOfFeatureMap.get(featureIdBuilder.toString())); - String duplicateSurrogateMessage = String.format(duplicateSurrogateFormatString, queryFqn, featureName, - className, packageUri, fqnInMap, contributorPlugins, contributorName); - throw new IllegalStateException(duplicateSurrogateMessage); - } - contributedSurrogateQueries.put(feature, surrogateQueryProvider); - contributingPluginOfFeatureMap.put(featureIdBuilder.toString(), contributorName); - } catch (Exception e) { - final Logger logger = Logger.getLogger(SurrogateQueryRegistry.class); - logger.error("Surrogate query registration failed", e); - } - } -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/internal/ExtensionBasedSystemDefaultBackendLoader.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/internal/ExtensionBasedSystemDefaultBackendLoader.java deleted file mode 100644 index 4339b70c..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/internal/ExtensionBasedSystemDefaultBackendLoader.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Zoltan Ujhelyi, IncQuery Labs - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.internal; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.Platform; -import tools.refinery.viatra.runtime.api.ViatraQueryEngineOptions; -import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendFactory; -import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendFactoryProvider; -import tools.refinery.viatra.runtime.util.ViatraQueryLoggingUtil; - -/** - * @since 2.0 - */ -public class ExtensionBasedSystemDefaultBackendLoader { - - private static final String EXTENSION_ID = "tools.refinery.viatra.runtime.querybackend"; - private static final ExtensionBasedSystemDefaultBackendLoader INSTANCE = new ExtensionBasedSystemDefaultBackendLoader(); - - public static ExtensionBasedSystemDefaultBackendLoader instance() { - return INSTANCE; - } - - public void loadKnownBackends() { - IQueryBackendFactory defaultBackend = null; - IQueryBackendFactory defaultCachingBackend = null; - IQueryBackendFactory defaultSearchBackend = null; - final IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_ID); - for (IConfigurationElement e : config) { - try { - IQueryBackendFactoryProvider provider = (IQueryBackendFactoryProvider) e - .createExecutableExtension("provider"); - if (provider.isSystemDefaultEngine()) { - defaultBackend = provider.getFactory(); - } - if (provider.isSystemDefaultCachingBackend()) { - defaultCachingBackend = provider.getFactory(); - } - if (provider.isSystemDefaultSearchBackend()) { - defaultSearchBackend = provider.getFactory(); - } - - } catch (CoreException ex) { - // In case errors try to continue with the next one - ViatraQueryLoggingUtil.getLogger(getClass()).error( - String.format("Error while initializing backend %s from plugin %s.", - e.getAttribute("backend"), e.getContributor().getName()), ex); - } - } - ViatraQueryEngineOptions.setSystemDefaultBackends(defaultBackend, defaultCachingBackend, defaultSearchBackend); - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/internal/apiimpl/ViatraQueryEngineImpl.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/internal/apiimpl/ViatraQueryEngineImpl.java index c2341273..a3a9d073 100644 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/internal/apiimpl/ViatraQueryEngineImpl.java +++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/internal/apiimpl/ViatraQueryEngineImpl.java @@ -34,9 +34,6 @@ import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory; import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory.MemoryType; import tools.refinery.viatra.runtime.matchers.util.IMultiLookup; import tools.refinery.viatra.runtime.matchers.util.Preconditions; -import tools.refinery.viatra.runtime.registry.IDefaultRegistryView; -import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistry; -import tools.refinery.viatra.runtime.registry.QuerySpecificationRegistry; import tools.refinery.viatra.runtime.util.ViatraQueryLoggingUtil; import java.lang.ref.WeakReference; @@ -227,17 +224,7 @@ public final class ViatraQueryEngineImpl extends AdvancedViatraQueryEngine @Override public ViatraQueryMatcher getMatcher(String patternFQN) { - IQuerySpecificationRegistry registry = QuerySpecificationRegistry.getInstance(); - IDefaultRegistryView view = registry.getDefaultView(); - IQuerySpecification> querySpecification = view - .getEntry(patternFQN).get(); - if (querySpecification != null) { - return getMatcher(querySpecification); - } else { - throw new ViatraQueryException(String.format( - "No matcher could be constructed for the pattern with FQN %s; if the generated matcher class is not available, please access for the first time using getMatcher(IQuerySpecification)", - patternFQN), "No matcher could be constructed for given pattern FQN."); - } + throw new UnsupportedOperationException("Query specification registry is not available"); } @Override diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/ExtensionBasedQuerySpecificationLoader.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/ExtensionBasedQuerySpecificationLoader.java deleted file mode 100644 index 40bf3e67..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/ExtensionBasedQuerySpecificationLoader.java +++ /dev/null @@ -1,303 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.Platform; -import tools.refinery.viatra.runtime.IExtensions; -import tools.refinery.viatra.runtime.api.IQueryGroup; -import tools.refinery.viatra.runtime.api.IQuerySpecification; -import tools.refinery.viatra.runtime.extensibility.IQueryGroupProvider; -import tools.refinery.viatra.runtime.extensibility.IQuerySpecificationProvider; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory.MemoryType; -import tools.refinery.viatra.runtime.matchers.util.IMemoryView; -import tools.refinery.viatra.runtime.matchers.util.IMultiLookup; -import tools.refinery.viatra.runtime.util.ViatraQueryLoggingUtil; - -/** - * Loader for the {@link QuerySpecificationRegistry} based on the query group extensions generated by the VIATRA Query - * builder. The loader has a single instance that processes the extensions on demand if the platform is running, caches - * the results and updates the {@link QuerySpecificationRegistry}. Note that the loader does not perform class loading - * on the query group if possible. - * - *

- * The class has a single instance accessible with {@link #getInstance()}. - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public class ExtensionBasedQuerySpecificationLoader { - - public static final String CONNECTOR_ID = "tools.refinery.viatra.runtime.querygroup.extension.based.connector"; - - private static final String DUPLICATE_QUERY_GROUP_MESSAGE = "Duplicate query group identifier %s for plugin %s (already contributed by %s)"; - private static final ExtensionBasedQuerySpecificationLoader INSTANCE = new ExtensionBasedQuerySpecificationLoader(); - - private IMultiLookup contributingPluginOfGroupMap = - CollectionsFactory.createMultiLookup(Object.class, MemoryType.SETS, Object.class); - private Map contributedQueryGroups; - - private ExtensionBasedSourceConnector sourceConnector; - - - /** - * @return the single instance of the loader. - */ - public static ExtensionBasedQuerySpecificationLoader getInstance() { - return INSTANCE; - } - - /** - * Loads the query specifications that are registered through extension points into the - * {@link QuerySpecificationRegistry}. - */ - public void loadRegisteredQuerySpecificationsIntoRegistry() { - ((QuerySpecificationRegistry) QuerySpecificationRegistry.getInstance()).addDelayedSourceConnector(getSourceConnector()); - } - - /** - * Return a source connector that can be used to load query specifications contributed through - * extensions into a {@link IQuerySpecificationRegistry}. - * - * @return the source connector - */ - public IRegistrySourceConnector getSourceConnector() { - if (this.sourceConnector == null) { - this.sourceConnector = new ExtensionBasedSourceConnector(); - } - return sourceConnector; - } - - private Map getRegisteredQueryGroups() { - if(contributedQueryGroups != null) { - return contributedQueryGroups; - } - contributedQueryGroups = new HashMap<>(); - if (Platform.isRunning()) { - for (IConfigurationElement e : Platform.getExtensionRegistry().getConfigurationElementsFor(IExtensions.QUERY_SPECIFICATION_EXTENSION_POINT_ID)) { - if (e.isValid()) { - processExtension(e); - } - } - } - return contributedQueryGroups; - } - - private void processExtension(IConfigurationElement el) { - String id = null; - try { - String contributorName = el.getContributor().getName(); - id = el.getAttribute("id"); - if(id == null) { - throw new IllegalStateException(String.format("Query group extension identifier is required (plug-in: %s)!", contributorName)); - } - - QueryGroupProvider provider = new QueryGroupProvider(el); - - QueryGroupProvider queryGroupInMap = contributedQueryGroups.get(id); - if(queryGroupInMap != null) { - IMemoryView contributorPlugins = contributingPluginOfGroupMap.lookupOrEmpty(id); - throw new IllegalStateException(String.format(DUPLICATE_QUERY_GROUP_MESSAGE, id, contributorName, contributorPlugins.distinctValues())); - } - - contributedQueryGroups.put(id, provider); - contributingPluginOfGroupMap.addPair(id, contributorName); - } catch (Exception e) { - // If there are serious compilation errors in the file loaded by the query registry, an error is thrown - if (id == null) { - id = "undefined in plugin.xml"; - } - ViatraQueryLoggingUtil.getLogger(ExtensionBasedQuerySpecificationLoader.class).error( - "[ExtensionBasedQuerySpecificationLoader] Exception during query specification registry initialization when preparing group: " - + id + "! " + e.getMessage(), e); - } - } - - /** - * @author Abel Hegedus - * - */ - private final class ExtensionBasedSourceConnector implements IRegistrySourceConnector { - - private Set listeners; - - public ExtensionBasedSourceConnector() { - this.listeners = new HashSet<>(); - } - - @Override - public String getIdentifier() { - return ExtensionBasedQuerySpecificationLoader.CONNECTOR_ID; - } - - @Override - public void addListener(IConnectorListener listener) { - Objects.requireNonNull(listener, "Listener must not be null!"); - boolean added = listeners.add(listener); - if(added) { - for (QueryGroupProvider queryGroupProvider : getRegisteredQueryGroups().values()) { - for (IQuerySpecificationProvider specificationProvider : queryGroupProvider.getQuerySpecificationProviders()) { - listener.querySpecificationAdded(this, specificationProvider); - } - } - } - } - - @Override - public void removeListener(IConnectorListener listener) { - Objects.requireNonNull(listener, "Listener must not be null!"); - listeners.remove(listener); - } - - @Override - public boolean includeSpecificationsInDefaultViews() { - return true; - } - } - - /** - * Provider implementation that uses the group extension to load the query group on-demand. - * It also provides the set of query FQNs that are part of the group without class loading. - * Once loaded, the query group is cached for future use. - * - * @author Abel Hegedus - */ - private static final class QueryGroupProvider implements IQueryGroupProvider { - - private static final String DUPLICATE_FQN_MESSAGE = "Duplicate FQN %s in query group extension point (plug-in %s)"; - private final IConfigurationElement element; - private IQueryGroup queryGroup; - private Set querySpecificationFQNs; - private Map querySpecificationMap; - - public QueryGroupProvider(IConfigurationElement element) { - this.element = element; - this.queryGroup = null; - this.querySpecificationFQNs = null; - this.querySpecificationMap = null; - } - - @Override - public IQueryGroup get() { - try{ - if(queryGroup == null) { - queryGroup = (IQueryGroup) element.createExecutableExtension("group"); - } - return queryGroup; - } catch (CoreException e) { - throw new IllegalStateException(e.getMessage(), e); - } - } - - @Override - public Set getQuerySpecificationFQNs() { - if(querySpecificationFQNs == null) { - Set fqns = new HashSet<>(); - for (IConfigurationElement e : element.getChildren("query-specification")) { - if (e.isValid()) { - String fqn = e.getAttribute("fqn"); - boolean added = fqns.add(fqn); - if(!added) { - String contributorName = e.getContributor().getName(); - throw new IllegalArgumentException(String.format(DUPLICATE_FQN_MESSAGE,fqn, contributorName)); - } - } - } - if(fqns.isEmpty()) { - // we must load the class and get the specifications - IQueryGroup loadedQueryGroup = get(); - for (IQuerySpecification specification : loadedQueryGroup.getSpecifications()) { - String fullyQualifiedName = specification.getFullyQualifiedName(); - boolean added = fqns.add(fullyQualifiedName); - if(!added) { - String contributorName = element.getContributor().getName(); - throw new IllegalArgumentException(String.format(DUPLICATE_FQN_MESSAGE, fullyQualifiedName, contributorName)); - } - } - } - // we will never change the set after initialization - querySpecificationFQNs = new HashSet<>(fqns); - } - return querySpecificationFQNs; - } - - @Override - public Set getQuerySpecificationProviders() { - return new HashSet<>(getQuerySpecificationMap().values()); - } - - private Map getQuerySpecificationMap() { - if(querySpecificationMap == null){ - querySpecificationMap = new HashMap<>(); - Set fqns = getQuerySpecificationFQNs(); - for (String fqn : fqns) { - querySpecificationMap.put(fqn, new GroupBasedQuerySpecificationProvider(fqn, this)); - } - } - return querySpecificationMap; - } - - } - - /** - * Provider implementation that uses the query group extension to load a query specification by its FQN. Note that - * the FQN of the provided query specification is set with the constructor and can be requested without loading the - * class. Once loaded, the query specification is cached for future use. - * - * @author Abel Hegedus - * - */ - private static final class GroupBasedQuerySpecificationProvider implements IQuerySpecificationProvider { - - private String queryFQN; - private QueryGroupProvider queryGroupProvider; - private IQuerySpecification specification; - - public GroupBasedQuerySpecificationProvider(String queryFQN, QueryGroupProvider queryGroupProvider) { - this.queryFQN = queryFQN; - this.queryGroupProvider = queryGroupProvider; - this.specification = null; - } - - @Override - public IQuerySpecification get() { - if(specification == null) { - if(queryGroupProvider.getQuerySpecificationFQNs().contains(queryFQN)) { - for (IQuerySpecification spec : queryGroupProvider.get().getSpecifications()) { - if(spec.getFullyQualifiedName().equals(queryFQN)){ - this.specification = spec; - } - } - } else { - throw new IllegalStateException(String.format("Could not find query specifition %s in group (plug-in %s)", queryFQN, queryGroupProvider.element.getContributor().getName())); - } - } - return specification; - } - - @Override - public String getFullyQualifiedName() { - return queryFQN; - } - - @Override - public String getSourceProjectName() { - return queryGroupProvider.element.getContributor().getName(); - } - } -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IConnectorListener.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IConnectorListener.java deleted file mode 100644 index 318415cc..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IConnectorListener.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry; - -import tools.refinery.viatra.runtime.extensibility.IQuerySpecificationProvider; - -/** - * Connector listeners are used to receive notifications on addition and removal of query specifications. - * The connector itself is also passed in the methods to allow the usage of the same listener on multiple connectors. - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public interface IConnectorListener { - - /** - * Called when a new query specification is added to the given connector. - * The provider interface is used to avoid class loading as long as possible. - * - * @param connector that has a new specification - * @param specificationProvider that wraps the new specification - */ - void querySpecificationAdded(IRegistrySourceConnector connector, IQuerySpecificationProvider specificationProvider); - - /** - * Called when a query specification is removed from the given connector. - * The provider interface is used to avoid class loading as long as possible. - * - * @param connector that has a removed specification - * @param specificationProvider that wraps the removed specification - */ - void querySpecificationRemoved(IRegistrySourceConnector connector, IQuerySpecificationProvider specificationProvider); -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IDefaultRegistryView.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IDefaultRegistryView.java deleted file mode 100644 index 9e3e0394..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IDefaultRegistryView.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry; - -import java.util.NoSuchElementException; - -import tools.refinery.viatra.runtime.api.IQueryGroup; - -/** - * The default registry view ensures that the fully qualified name of entries are unique and provides an additional - * method for retrieving the query group of entries for easy initialization. - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public interface IDefaultRegistryView extends IRegistryView { - - /** - * @return a query group containing all query specifications - */ - IQueryGroup getQueryGroup(); - - /** - * @param fullyQualifiedName - * of the entry that is requested - * @return the entry with the given FQN - * @throws NoSuchElementException if there is no such entry in the default view - */ - IQuerySpecificationRegistryEntry getEntry(String fullyQualifiedName); -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IQuerySpecificationRegistry.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IQuerySpecificationRegistry.java deleted file mode 100644 index 97a17f0e..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IQuerySpecificationRegistry.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry; - -/** - * The query specification registry is used to manage query specifications provided by multiple connectors which can - * dynamically add and remove specifications. Users can read the contents of the registry through views that are also - * dynamically updated when the registry is changed by the connectors. - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public interface IQuerySpecificationRegistry { - - /** - * Cannot register connectors with the same identifier twice. No change occurs if the identifier is already used. - * - * @param connector - * cannot be null - * @return false if a connector with the given identifier has already been added, true otherwise - */ - boolean addSource(IRegistrySourceConnector connector); - - /** - * Removes the connector if it was registered. No change occurs if the identifier of the connector was not used - * before. - * - * @param connector - * cannot be null - * @return false if a registered connector with the given identifier was not found, true if it was successfully - * removed - */ - boolean removeSource(IRegistrySourceConnector connector); - - /** - * Returns a default view instance that contains query specification entries that indicate their inclusion in - * default views. If there are entries with the same FQN, only the last added will be included in the view to avoid - * duplicate FQNs. - * - * @return the default view instance - */ - IDefaultRegistryView getDefaultView(); - - /** - * Creates a view which contains query specification entries that indicate their inclusion in default views. This - * view will also be incrementally updated on registry changes and accepts listeners to notify on changes. - * - * @return a new view instance - */ - IRegistryView createView(); - - /** - * Creates a view which contains registered query specifications that are considered relevant by the passed filter. - * This view will also be incrementally updated on registry changes and accepts listeners to notify on changes. - * - * @return a new filtered view instance - */ - IRegistryView createView(IRegistryViewFilter filter); - - /** - * Creates a view which is instantiated by the factory and is connected to the registry. This - * view will also be incrementally updated on registry changes and accepts listeners to notify on changes. - * - * @return a new view instance - */ - IRegistryView createView(IRegistryViewFactory factory); -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IQuerySpecificationRegistryChangeListener.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IQuerySpecificationRegistryChangeListener.java deleted file mode 100644 index defdd2ab..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IQuerySpecificationRegistryChangeListener.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry; - -/** - * Listener interface for providing update notifications of views to users. It is used for propagating changes from the - * query specification registry to the views and from the views to users. - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public interface IQuerySpecificationRegistryChangeListener { - - /** - * Called when a new entry is added to the registry. - * - * @param entry that is added - */ - void entryAdded(IQuerySpecificationRegistryEntry entry); - - /** - * Called when an existing entry is removed from the registry. - * - * @param entry that is removed - */ - void entryRemoved(IQuerySpecificationRegistryEntry entry); - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IQuerySpecificationRegistryEntry.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IQuerySpecificationRegistryEntry.java deleted file mode 100644 index 5009d74b..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IQuerySpecificationRegistryEntry.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry; - -import tools.refinery.viatra.runtime.extensibility.IQuerySpecificationProvider; - -/** - * The query specification registry entry interface can return the identifier of the source that added it to the - * registry. It is provider based and can delay class loading of the wrapped {@link IQuerySpecification} until needed. - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public interface IQuerySpecificationRegistryEntry extends IQuerySpecificationProvider { - - /** - * @return the identifier of the registry source that contributed the specification - */ - String getSourceIdentifier(); - - /** - * Returns whether the query specification was provided by an identifiable project. - */ - boolean isFromProject(); - - /** - * Collects the name of the project that is registered this specification to the registry. - * If {@link #getSourceIdentifier()} is false, it returns null. - */ - String getSourceProjectName(); - - /** - * @return true if the entry should be included in default views (created without any filters) - */ - boolean includeInDefaultViews(); - - /** - * @return the wrapped {@link IQuerySpecificationProvider} or itself - */ - IQuerySpecificationProvider getProvider(); -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IRegistrySourceConnector.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IRegistrySourceConnector.java deleted file mode 100644 index 94c68d1b..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IRegistrySourceConnector.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry; - -/** - * A registry source connector can provide query specifications to listeners (e.g. {@link IQuerySpecificationRegistry}). - * The connector interface does not support direct access to query specifications, instead it sends existing specifications - * to listeners on addition and sends notifications to listeners when a change occurs in the set of specifications. - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public interface IRegistrySourceConnector { - - /** - * The connector must return the same identifier every time it is invoked! - * - * @return unique identifier of the connector - */ - String getIdentifier(); - - /** - * - * @return true if the specifications of the connector should be included in default views - */ - boolean includeSpecificationsInDefaultViews(); - - /** - * Add a listener to get updates on changes in the query specifications available from the connector. When the - * listener is added, the connector is expected to call the listener with each existing query specification. - * - * @param listener that should be added - */ - void addListener(IConnectorListener listener); - - /** - * Removes an already registered listener and stops sending updates. The connector is not required to send any - * updates before returning from this method, but should not send any events after this method returns. - * - * @param listener that should be removed - */ - void removeListener(IConnectorListener listener); -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IRegistryView.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IRegistryView.java deleted file mode 100644 index acf49b76..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IRegistryView.java +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry; - -import java.util.Set; - -/** - * The registry view is the primary interface for users to interact with the query specifications in an - * {@link IQuerySpecificationRegistry}. Views are created using the createView methods of registry and their content is - * also dynamically updated by the registry. - * - * The view contains a set of {@link IQuerySpecificationRegistryEntry} objects that can be used to access the query - * specifications themselves through the get() method. - * - * Users can check the contents of the view and add listeners to get notifications on view changes (added or removed - * entries). - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public interface IRegistryView extends IQuerySpecificationRegistryChangeListener { - - /** - * @return an immutable copy of all entries found in the view - */ - Iterable getEntries(); - - /** - * @return the set of FQNs for the query specifications in the view - */ - Set getQuerySpecificationFQNs(); - - /** - * @param fullyQualifiedName - * that is looked up in the view - * @return true if the view contains an entry with given FQN, false otherwise - */ - boolean hasQuerySpecificationFQN(String fullyQualifiedName); - - /** - * @param fullyQualifiedName - * of the entries that are requested - * @return the possible empty set of entries with the given FQN - */ - Set getEntries(String fullyQualifiedName); - - /** - * Adds a listener to the view that will be notified when an entry is added to or removed from the view. - * - * @param listener that is added - */ - void addViewListener(IQuerySpecificationRegistryChangeListener listener); - - /** - * Removes a listener that was previously added to the view. - * - * @param listener that is removed - */ - void removeViewListener(IQuerySpecificationRegistryChangeListener listener); - - /** - * @return the registry underlying the view - */ - IQuerySpecificationRegistry getRegistry(); -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IRegistryViewFactory.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IRegistryViewFactory.java deleted file mode 100644 index 990902d3..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IRegistryViewFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry; - -/** - * This interface can be used to ask the registry to construct specific view instances. The factory is responsible for - * instantiating the view, but the registry is responsible for establishing the connection with the internal data store - * and to fill up the view with entries. Instances of the factory are intended to be passed to - * {@link IQuerySpecificationRegistry#createView(IRegistryViewFactory)} and only the view instance returned by that - * method can be considered initialized. - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public interface IRegistryViewFactory { - - /** - * Instantiate a new view object and store the reference to the registry. - * This method should only be called by an {@link IQuerySpecificationRegistry}. - * - * @param registry that will be connected to the view - * @return the new instance of the view - * @noreference This method is not intended to be referenced by clients. - */ - IRegistryView createView(IQuerySpecificationRegistry registry); - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IRegistryViewFilter.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IRegistryViewFilter.java deleted file mode 100644 index fa13327f..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/IRegistryViewFilter.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry; - -/** - * The registry view filter can control which entries are added and removed from an {@link IRegistryView}. - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public interface IRegistryViewFilter { - - /** - * This method controls whether a registry entry is added to the view or not. The filtering is called before - * checking the uniqueness of fully qualified names, and relevant entries can overwrite existing entries with the - * same FQN. - * - * Note that filters should usually return the same value for the same entry on multiple invocations. - * - * @param entry - * that is checked - * @return true, if the entry is relevant for the view, false otherwise - */ - boolean isEntryRelevant(IQuerySpecificationRegistryEntry entry); - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/QuerySpecificationRegistry.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/QuerySpecificationRegistry.java deleted file mode 100644 index 139dde1c..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/QuerySpecificationRegistry.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry; - -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -import tools.refinery.viatra.runtime.registry.impl.QuerySpecificationRegistryImpl; - -/** - * Registry for query specifications that can be accessed using fully qualified names through views. - * Additional query specifications can be added using {@link IRegistrySourceConnector}s. - * - *

- * When running as an OSGi plug-in, the generated query specifications registered through extensions are automatically loaded - * into the registry by the {@link ExtensionBasedQuerySpecificationLoader} class. - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public class QuerySpecificationRegistry implements IQuerySpecificationRegistry { - - private static final QuerySpecificationRegistry INSTANCE = new QuerySpecificationRegistry(); - - /** - * @return the singleton query specification registry instance - */ - public static IQuerySpecificationRegistry getInstance() { - return INSTANCE; - } - - private final QuerySpecificationRegistryImpl internalRegistry; - /** - * Connectors that should not be immediately loaded into the registry. - */ - private final Set delayedConnectors; - - /** - * Hidden constructor for singleton instance - */ - protected QuerySpecificationRegistry() { - this.internalRegistry = new QuerySpecificationRegistryImpl(); - this.delayedConnectors = new HashSet<>(); - - } - - /** - * @return the internal registry after adding delayed source connectors - */ - protected IQuerySpecificationRegistry getInternalRegistry() { - if(!delayedConnectors.isEmpty()) { - final Iterator it = delayedConnectors.iterator(); - while (it.hasNext()) { - final IRegistrySourceConnector connector = it.next(); - internalRegistry.addSource(connector); - it.remove(); - } - } - return internalRegistry; - } - - /** - * When the registry adds itself as a listener to connectors, it must send all specification providers - * to the registry. However, when {@link ExtensionBasedQuerySpecificationLoader} is triggered during the - * activation of the plugin, the individual query specification classes cannot be loaded yet. To avoid this, - * the connector of the loader is delayed until needed. - * - * @param connector that should be delayed before adding to the registry - */ - protected void addDelayedSourceConnector(IRegistrySourceConnector connector) { - delayedConnectors.add(connector); - } - - @Override - public boolean addSource(IRegistrySourceConnector connector) { - return getInternalRegistry().addSource(connector); - } - - @Override - public boolean removeSource(IRegistrySourceConnector connector) { - return getInternalRegistry().removeSource(connector); - } - - @Override - public IDefaultRegistryView getDefaultView() { - return getInternalRegistry().getDefaultView(); - } - - @Override - public IRegistryView createView() { - return getInternalRegistry().createView(); - } - - @Override - public IRegistryView createView(IRegistryViewFilter filter) { - return getInternalRegistry().createView(filter); - } - - @Override - public IRegistryView createView(IRegistryViewFactory factory) { - return getInternalRegistry().createView(factory); - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/connector/AbstractRegistrySourceConnector.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/connector/AbstractRegistrySourceConnector.java deleted file mode 100644 index 0e2ef273..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/connector/AbstractRegistrySourceConnector.java +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry.connector; - -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; - -import tools.refinery.viatra.runtime.registry.IConnectorListener; -import tools.refinery.viatra.runtime.registry.IRegistrySourceConnector; - -/** - * Abstract registry source connector implementation that stores the identifier and listener set. - * - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public abstract class AbstractRegistrySourceConnector implements IRegistrySourceConnector { - - protected Set listeners; - private String identifier; - private boolean includeInDefaultViews; - - /** - * Creates an instance of the connector with the given identifier. The identifier should be unique if you want to - * add it to a registry as a source. - * - * @param identifier - * of the newly created connector - * @param includeInDefaultViews - * true if the specifications in the connector should be included in default views - */ - public AbstractRegistrySourceConnector(String identifier, boolean includeInDefaultViews) { - super(); - Objects.requireNonNull(identifier, "Identifier must not be null!"); - this.identifier = identifier; - this.includeInDefaultViews = includeInDefaultViews; - this.listeners = new HashSet<>(); - } - - @Override - public String getIdentifier() { - return identifier; - } - - @Override - public boolean includeSpecificationsInDefaultViews() { - return includeInDefaultViews; - } - - @Override - public void addListener(IConnectorListener listener) { - Objects.requireNonNull(listener, "Listener must not be null!"); - boolean added = listeners.add(listener); - if (added) { - sendQuerySpecificationsToListener(listener); - } - } - - @Override - public void removeListener(IConnectorListener listener) { - Objects.requireNonNull(listener, "Listener must not be null!"); - listeners.remove(listener); - } - - /** - * Subclasses should send add notifications for each specification in the connector to the given listener. - * - * @param listener that should receive the notifications - */ - protected abstract void sendQuerySpecificationsToListener(IConnectorListener listener); - -} \ No newline at end of file diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/connector/QueryGroupProviderSourceConnector.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/connector/QueryGroupProviderSourceConnector.java deleted file mode 100644 index e6f0adf0..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/connector/QueryGroupProviderSourceConnector.java +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry.connector; - -import java.util.Objects; - -import tools.refinery.viatra.runtime.extensibility.IQueryGroupProvider; -import tools.refinery.viatra.runtime.extensibility.IQuerySpecificationProvider; -import tools.refinery.viatra.runtime.registry.IConnectorListener; - -/** - * Source connector implementation that uses a {@link IQueryGroupProvider} to provide a query specifications into the - * registry. The query group can be later updated which triggers the removal of all specifications of the old group and - * the addition of all specifications from the new group. - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public class QueryGroupProviderSourceConnector extends AbstractRegistrySourceConnector { - - IQueryGroupProvider queryGroupProvider; - - /** - * Creates an instance of the connector with the given identifier and the query group provider. The identifier - * should be unique if you want to add it to a registry as a source. - * - * @param identifier - * of the newly created connector - * @param provider - * that contains the query specifications handled by the connector - * @param includeInDefaultViews - * true if the specifications in the connector should be included in default views - */ - public QueryGroupProviderSourceConnector(String identifier, IQueryGroupProvider provider, boolean includeInDefaultViews) { - super(identifier, includeInDefaultViews); - this.queryGroupProvider = provider; - } - - /** - * Update the query group of the connector, which triggers the removal of all specifications on the old group and - * addition of all specifications in the given group. - * - * @param queryGroupProvider - * the queryGroupProvider to set - * @param includeInDefaultViews - * true if the specifications in the connector should be included in default views - */ - public void setQueryGroupProvider(IQueryGroupProvider queryGroupProvider) { - Objects.requireNonNull(queryGroupProvider, "Query group provider must not be null!"); - IQueryGroupProvider oldProvider = this.queryGroupProvider; - - for (IQuerySpecificationProvider specificationProvider : oldProvider.getQuerySpecificationProviders()) { - for (IConnectorListener iConnectorListener : listeners) { - iConnectorListener.querySpecificationRemoved(this, specificationProvider); - } - } - for (IQuerySpecificationProvider specificationProvider : queryGroupProvider.getQuerySpecificationProviders()) { - for (IConnectorListener iConnectorListener : listeners) { - iConnectorListener.querySpecificationAdded(this, specificationProvider); - } - } - - this.queryGroupProvider = queryGroupProvider; - } - - @Override - protected void sendQuerySpecificationsToListener(IConnectorListener listener) { - for (IQuerySpecificationProvider specificationProvider : queryGroupProvider.getQuerySpecificationProviders()) { - listener.querySpecificationAdded(this, specificationProvider); - } - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/connector/SpecificationMapSourceConnector.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/connector/SpecificationMapSourceConnector.java deleted file mode 100644 index e5778950..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/connector/SpecificationMapSourceConnector.java +++ /dev/null @@ -1,147 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry.connector; - -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Objects; -import java.util.Set; - -import tools.refinery.viatra.runtime.extensibility.IQuerySpecificationProvider; -import tools.refinery.viatra.runtime.extensibility.SingletonQuerySpecificationProvider; -import tools.refinery.viatra.runtime.registry.IConnectorListener; - -/** - * A simple connector implementation that allows users to simply add and remove specifications. These changes are - * propagated to listeners (e.g. the registry). Note that duplicate FQNs are not allowed in a given connector. - * - * @author Abel Hegedus - * @since 1.3 - * - */ -public class SpecificationMapSourceConnector extends AbstractRegistrySourceConnector { - - private static final String DUPLICATE_MESSAGE = "Duplicate FQN %s cannot be added to connector"; - private Map specificationProviderMap; - - /** - * Creates an instance of the connector with the given identifier. The identifier should be unique if you want to - * add it to a registry as a source. - * - * @param identifier - * of the newly created connector - * @param includeInDefaultViews - * true if the specifications in the connector should be included in default views - */ - public SpecificationMapSourceConnector(String identifier, boolean includeInDefaultViews) { - super(identifier, includeInDefaultViews); - this.specificationProviderMap = new HashMap<>(); - } - - /** - * Creates an instance of the connector with the given identifier and fills it up with the given specification - * providers. The identifier should be unique if you want to add it to a registry as a source. - * - * @param identifier - * of the newly created connector - * @param specificationProviders - * the initial set of specifications in the connector - * @param includeInDefaultViews - * true if the specifications in the connector should be included in default views - */ - public SpecificationMapSourceConnector(String identifier, Set specificationProviders, boolean includeInDefaultViews) { - this(identifier, includeInDefaultViews); - for (IQuerySpecificationProvider provider : specificationProviders) { - addQuerySpecificationProvider(provider); - } - } - - /** - * Creates an instance of the connector with the given identifier and fills it up with the specification providers - * from the given {@link SpecificationMapSourceConnector}. The identifier should be unique if you want to add it to - * a registry as a source. - * - * @param identifier - * of the newly created connector - * @param connector - * that contains the specifications to copy into the new instance - * @param includeInDefaultViews - * true if the specifications in the connector should be included in default views - */ - public SpecificationMapSourceConnector(String identifier, SpecificationMapSourceConnector connector, boolean includeInDefaultViews) { - this(identifier, includeInDefaultViews); - this.specificationProviderMap.putAll(connector.specificationProviderMap); - } - - /** - * Adds a query specification to the connector. - * If you have an {@link IQuerySpecification} object, use {@link SingletonQuerySpecificationProvider}. - * - * @param provider to add to the connector - * @throws IllegalArgumentException if the connector already contains a specification with the same FQN - */ - public void addQuerySpecificationProvider(IQuerySpecificationProvider provider) { - Objects.requireNonNull(provider, "Provider must not be null!"); - String fullyQualifiedName = provider.getFullyQualifiedName(); - if (!specificationProviderMap.containsKey(fullyQualifiedName)) { - specificationProviderMap.put(fullyQualifiedName, provider); - for (IConnectorListener listener : listeners) { - listener.querySpecificationAdded(this, provider); - } - } else { - throw new IllegalArgumentException(String.format(DUPLICATE_MESSAGE, fullyQualifiedName)); - } - } - - /** - * Remove a specification that has been added with the given FQN. - * - * @param fullyQualifiedName - * @throws NoSuchElementException if the connector does not contain a specification with the given FQN - */ - public void removeQuerySpecificationProvider(String fullyQualifiedName) { - Objects.requireNonNull(fullyQualifiedName, "Fully qualified name must not be null!"); - IQuerySpecificationProvider provider = specificationProviderMap.remove(fullyQualifiedName); - if (provider == null) { - throw new NoSuchElementException( - String.format("Connector does not contain specification with FQN %s", fullyQualifiedName)); - } - for (IConnectorListener listener : listeners) { - listener.querySpecificationRemoved(this, provider); - } - } - - /** - * @return the immutable copy of the set of FQNs for the added query specifications - */ - public Set getQuerySpecificationFQNs() { - return Collections.unmodifiableSet(new HashSet<>(specificationProviderMap.keySet())); - } - - /** - * - * @param fullyQualifiedName that is checked - * @return true if a specification with the given FQN exists in the connector, false otherwise - */ - public boolean hasQuerySpecificationFQN(String fullyQualifiedName) { - Objects.requireNonNull(fullyQualifiedName, "FQN must not be null!"); - return specificationProviderMap.containsKey(fullyQualifiedName); - } - - @Override - protected void sendQuerySpecificationsToListener(IConnectorListener listener) { - for (IQuerySpecificationProvider provider : specificationProviderMap.values()) { - listener.querySpecificationAdded(this, provider); - } - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/data/QuerySpecificationStore.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/data/QuerySpecificationStore.java deleted file mode 100644 index 649527b6..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/data/QuerySpecificationStore.java +++ /dev/null @@ -1,38 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry.data; - -import java.util.Map; -import java.util.TreeMap; - -/** - * Internal data storage object that represents a query specification registry with a set of sources driven by - * connectors. The sources must have unique identifiers. - * - * @author Abel Hegedus - * - */ -public class QuerySpecificationStore { - - private Map sources; - - /** - * Creates a new instance with an empty identifier to source map. - */ - public QuerySpecificationStore() { - this.sources = new TreeMap<>(); - } - - /** - * @return the live, modifiable identifier to source map - */ - public Map getSources() { - return sources; - } -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/data/RegistryEntryImpl.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/data/RegistryEntryImpl.java deleted file mode 100644 index 758885e2..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/data/RegistryEntryImpl.java +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry.data; - -import tools.refinery.viatra.runtime.api.IQuerySpecification; -import tools.refinery.viatra.runtime.extensibility.IQuerySpecificationProvider; -import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistryEntry; - -/** - * Internal data storage object that represents a query specification entry. The entry contains an - * {@link IQuerySpecificationProvider} and has a reference to the source that contains it. - * - * @author Abel Hegedus - * - */ -public class RegistryEntryImpl implements IQuerySpecificationRegistryEntry { - - private IQuerySpecificationProvider provider; - private RegistrySourceImpl source; - - /** - * Creates a new instance with the given source and the given provider. - * - * @param source - * that contains the new entry - * @param provider - * that wraps the specification represented by the entry - */ - public RegistryEntryImpl(RegistrySourceImpl source, IQuerySpecificationProvider provider) { - this.source = source; - this.provider = provider; - } - - /** - * @return the source that contains this entry - */ - public RegistrySourceImpl getSource() { - return source; - } - - @Override - public String getSourceIdentifier() { - return source.getIdentifier(); - } - - @Override - public boolean includeInDefaultViews() { - return getSource().includeEntriesInDefaultViews(); - } - - @Override - public String getFullyQualifiedName() { - return provider.getFullyQualifiedName(); - } - - @Override - public IQuerySpecification get() { - return provider.get(); - } - - @Override - public IQuerySpecificationProvider getProvider() { - return provider; - } - - @Override - public boolean isFromProject() { - return provider.getSourceProjectName() != null; - } - - @Override - public String getSourceProjectName() { - return provider.getSourceProjectName(); - } -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/data/RegistrySourceImpl.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/data/RegistrySourceImpl.java deleted file mode 100644 index 83c3b920..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/data/RegistrySourceImpl.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry.data; - -import java.util.Map; -import java.util.TreeMap; - -/** - * Internal data storage object that represents a query specification source driven by a connector. The source must have - * unique identifier that is copied from the connector. The source uses a FQN to entry map to manage registry entries. - * - * @author Abel Hegedus - * - */ -public class RegistrySourceImpl { - - private String identifier; - private boolean includeInDefaultViews; - private QuerySpecificationStore querySpecificationStore; - private Map fqnToEntryMap; - - /** - * Creates a new source with the given identifier and an empty entry map. - * - * @param identifier - * for the source - * @param querySpecificationStore - * that contains this source - * @param includeInDefaultViews - * true if the entries of the source should be included in default views - */ - public RegistrySourceImpl(String identifier, QuerySpecificationStore querySpecificationStore, boolean includeInDefaultViews) { - this.identifier = identifier; - this.includeInDefaultViews = includeInDefaultViews; - this.querySpecificationStore = querySpecificationStore; - this.fqnToEntryMap = new TreeMap<>(); - } - - /** - * @return the identifier of the source - */ - public String getIdentifier() { - return identifier; - } - - /** - * @return true if the entries in the source should be included in default views - */ - public boolean includeEntriesInDefaultViews() { - return includeInDefaultViews; - } - - /** - * @return the store that contains the source - */ - public QuerySpecificationStore getStore() { - return querySpecificationStore; - } - - /** - * @return the live, modifiable FQN to entry map - */ - public Map getFqnToEntryMap() { - return fqnToEntryMap; - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/FilteringRegistryView.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/FilteringRegistryView.java deleted file mode 100644 index 164a30d3..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/FilteringRegistryView.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry.impl; - -import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistry; -import tools.refinery.viatra.runtime.registry.IRegistryViewFilter; -import tools.refinery.viatra.runtime.registry.view.AbstractRegistryView; -import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistryEntry; - -/** - * Registry view implementation that uses a filter to delegate the decision on whether - * a given specification is relevant to the view. - * - * @author Abel Hegedus - * - */ -public class FilteringRegistryView extends AbstractRegistryView { - - private IRegistryViewFilter filter; - - /** - * Creates a new filtering view instance. - * - * @param registry that defines the view - * @param filter that is used for deciding relevancy - */ - public FilteringRegistryView(IQuerySpecificationRegistry registry, IRegistryViewFilter filter, boolean allowDuplicateFQNs) { - super(registry, allowDuplicateFQNs); - this.filter = filter; - } - - @Override - protected boolean isEntryRelevant(IQuerySpecificationRegistryEntry entry) { - return filter.isEntryRelevant(entry); - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/GlobalRegistryView.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/GlobalRegistryView.java deleted file mode 100644 index 75d730b6..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/GlobalRegistryView.java +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry.impl; - -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.stream.Collectors; - -import tools.refinery.viatra.runtime.api.IQueryGroup; -import tools.refinery.viatra.runtime.api.LazyLoadingQueryGroup; -import tools.refinery.viatra.runtime.registry.IDefaultRegistryView; -import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistry; -import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistryEntry; -import tools.refinery.viatra.runtime.registry.view.AbstractRegistryView; - -/** - * Registry view implementation that considers specifications relevant if they are included in default views. - * - * @author Abel Hegedus - * - */ -public class GlobalRegistryView extends AbstractRegistryView implements IDefaultRegistryView { - - /** - * Creates a new instance of the global view. - * - * @param registry that defines the view - */ - public GlobalRegistryView(IQuerySpecificationRegistry registry) { - super(registry, false); - } - - @Override - protected boolean isEntryRelevant(IQuerySpecificationRegistryEntry entry) { - return entry.includeInDefaultViews(); - } - - @Override - public IQueryGroup getQueryGroup() { - Set allQueries = - fqnToEntryMap.distinctValuesStream().collect(Collectors.toSet()); - IQueryGroup queryGroup = LazyLoadingQueryGroup.of(allQueries); - return queryGroup; - } - - @Override - public IQuerySpecificationRegistryEntry getEntry(String fullyQualifiedName) { - Set entries = getEntries(fullyQualifiedName); - if(entries.isEmpty()){ - throw new NoSuchElementException("Cannot find entry with FQN " + fullyQualifiedName); - } - if(entries.size() > 1) { - throw new IllegalStateException("Global view must never contain duplicated FQNs!"); - } - IQuerySpecificationRegistryEntry entry = entries.iterator().next(); - return entry; - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/QuerySpecificationRegistryImpl.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/QuerySpecificationRegistryImpl.java deleted file mode 100644 index 63306e93..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/QuerySpecificationRegistryImpl.java +++ /dev/null @@ -1,177 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry.impl; - -import static tools.refinery.viatra.runtime.matchers.util.Preconditions.checkArgument; - -import java.util.Map; - -import org.apache.log4j.Logger; -import tools.refinery.viatra.runtime.extensibility.IQuerySpecificationProvider; -import tools.refinery.viatra.runtime.registry.IConnectorListener; -import tools.refinery.viatra.runtime.registry.IDefaultRegistryView; -import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistry; -import tools.refinery.viatra.runtime.registry.IRegistryView; -import tools.refinery.viatra.runtime.registry.IRegistryViewFactory; -import tools.refinery.viatra.runtime.registry.IRegistryViewFilter; -import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistryChangeListener; -import tools.refinery.viatra.runtime.registry.IRegistrySourceConnector; -import tools.refinery.viatra.runtime.registry.data.QuerySpecificationStore; -import tools.refinery.viatra.runtime.registry.data.RegistryEntryImpl; -import tools.refinery.viatra.runtime.registry.data.RegistrySourceImpl; -import tools.refinery.viatra.runtime.util.ViatraQueryLoggingUtil; - -/** - * This is the default implementation of the {@link IQuerySpecificationRegistry} interface. - * It uses a {@link QuerySpecificationStore} to keep track of sources and entries. - * It uses a {@link RegistryChangeMultiplexer} to update all views and a single {@link IConnectorListener} - * to subscribe to sources added to the registry. - * - * @author Abel Hegedus - * - */ -public class QuerySpecificationRegistryImpl implements IQuerySpecificationRegistry { - - private static final String CONNECTOR_NULL_MSG = "Connector cannot be null"; - private final QuerySpecificationStore querySpecificationStore; - private final IConnectorListener connectorListener; - private final RegistryChangeMultiplexer multiplexer; - private final Logger logger; - private IDefaultRegistryView defaultView = null; - - /** - * Creates a new instance of the registry - */ - public QuerySpecificationRegistryImpl() { - this.querySpecificationStore = new QuerySpecificationStore(); - this.connectorListener = new RegistryUpdaterConnectorListener(); - this.multiplexer = new RegistryChangeMultiplexer(); - this.logger = ViatraQueryLoggingUtil.getLogger(IQuerySpecificationRegistry.class); - } - - @Override - public boolean addSource(IRegistrySourceConnector connector) { - checkArgument(connector != null, CONNECTOR_NULL_MSG); - String identifier = connector.getIdentifier(); - Map sources = querySpecificationStore.getSources(); - if(sources.containsKey(identifier)){ - return false; - } - RegistrySourceImpl source = new RegistrySourceImpl(identifier, querySpecificationStore, connector.includeSpecificationsInDefaultViews()); - sources.put(identifier, source); - connector.addListener(connectorListener); - logger.debug("Source added: " + source.getIdentifier()); - return true; - } - - @Override - public boolean removeSource(IRegistrySourceConnector connector) { - checkArgument(connector != null, CONNECTOR_NULL_MSG); - String identifier = connector.getIdentifier(); - Map sources = querySpecificationStore.getSources(); - if(!sources.containsKey(identifier)){ - return false; - } - connector.removeListener(connectorListener); - RegistrySourceImpl source = sources.remove(identifier); - for (RegistryEntryImpl entry : source.getFqnToEntryMap().values()) { - multiplexer.entryRemoved(entry); - } - logger.debug("Source removed: " + source.getIdentifier()); - return true; - } - - /** - * @return the internal store of the registry - */ - protected QuerySpecificationStore getStore() { - return querySpecificationStore; - } - - @Override - public IRegistryView createView() { - return createGlobalView(); - } - - private GlobalRegistryView createGlobalView() { - GlobalRegistryView registryView = new GlobalRegistryView(this); - initializeChangeListener(registryView); - return registryView; - } - - protected void initializeChangeListener(IQuerySpecificationRegistryChangeListener listener) { - // send existing entries to aspect - for (RegistrySourceImpl source : querySpecificationStore.getSources().values()) { - Map entryMap = source.getFqnToEntryMap(); - for (RegistryEntryImpl entry : entryMap.values()) { - listener.entryAdded(entry); - } - } - multiplexer.addListener(listener); - } - - @Override - public IRegistryView createView(IRegistryViewFilter filter) { - checkArgument(filter != null, "Filter cannot be null"); - FilteringRegistryView registryView = new FilteringRegistryView(this, filter, false); - initializeChangeListener(registryView); - return registryView; - } - - /** - * Internal connector listener implementation for updating internal store and propagating changes to views. - * - * @author Abel Hegedus - * - */ - private final class RegistryUpdaterConnectorListener implements IConnectorListener { - @Override - public void querySpecificationAdded(IRegistrySourceConnector connector, IQuerySpecificationProvider specification) { - String identifier = connector.getIdentifier(); - RegistrySourceImpl source = querySpecificationStore.getSources().get(identifier); - String fullyQualifiedName = specification.getFullyQualifiedName(); - RegistryEntryImpl registryEntry = new RegistryEntryImpl(source, specification); - RegistryEntryImpl oldEntry = source.getFqnToEntryMap().put(fullyQualifiedName, registryEntry); - if(oldEntry != null) { - logger.warn(String.format("Specification added with existing FQN %s in source %s", fullyQualifiedName, identifier)); - multiplexer.entryRemoved(oldEntry); - } - multiplexer.entryAdded(registryEntry); - - } - - @Override - public void querySpecificationRemoved(IRegistrySourceConnector connector, IQuerySpecificationProvider specification) { - String identifier = connector.getIdentifier(); - RegistrySourceImpl source = querySpecificationStore.getSources().get(identifier); - String fullyQualifiedName = specification.getFullyQualifiedName(); - RegistryEntryImpl registryEntry = source.getFqnToEntryMap().remove(fullyQualifiedName); - if(registryEntry != null) { - multiplexer.entryRemoved(registryEntry); - } - } - } - - @Override - public IDefaultRegistryView getDefaultView() { - if(this.defaultView == null){ - this.defaultView = createGlobalView(); - } - return this.defaultView; - } - - @Override - public IRegistryView createView(IRegistryViewFactory factory) { - IRegistryView registryView = factory.createView(this); - initializeChangeListener(registryView); - return registryView; - } - - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/RegistryChangeMultiplexer.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/RegistryChangeMultiplexer.java deleted file mode 100644 index 450f36b8..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/RegistryChangeMultiplexer.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry.impl; - -import java.util.Collections; -import java.util.Set; -import java.util.WeakHashMap; - -import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistryChangeListener; -import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistryEntry; - -/** - * Listener implementation that propagates all changes to a set of listeners. - * The listeners are stored with weak references to avoid a need for disposal. - * - * @author Abel Hegedus - * - */ -public class RegistryChangeMultiplexer implements IQuerySpecificationRegistryChangeListener { - - private Set listeners; - - /** - * Creates a new instance of the multiplexer. - */ - public RegistryChangeMultiplexer() { - this.listeners = Collections.newSetFromMap(new WeakHashMap()); - } - - /** - * Adds a weak reference on the listener to the multiplexer. The listener will receive all further notifications and - * does not have to be removed, since the multiplexer will not keep it in memory when it can be collected. - */ - public boolean addListener(IQuerySpecificationRegistryChangeListener listener) { - return listeners.add(listener); - } - - @Override - public void entryAdded(IQuerySpecificationRegistryEntry entry) { - for (IQuerySpecificationRegistryChangeListener listener : listeners) { - listener.entryAdded(entry); - } - } - - @Override - public void entryRemoved(IQuerySpecificationRegistryEntry entry) { - for (IQuerySpecificationRegistryChangeListener listener : listeners) { - listener.entryRemoved(entry); - } - } - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/view/AbstractRegistryView.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/view/AbstractRegistryView.java deleted file mode 100644 index 7b3c34ba..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/view/AbstractRegistryView.java +++ /dev/null @@ -1,150 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.registry.view; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; -import java.util.stream.Collectors; - -import org.apache.log4j.Logger; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory.MemoryType; -import tools.refinery.viatra.runtime.matchers.util.IMemoryView; -import tools.refinery.viatra.runtime.matchers.util.IMultiLookup; -import tools.refinery.viatra.runtime.matchers.util.Preconditions; -import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistry; -import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistryChangeListener; -import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistryEntry; -import tools.refinery.viatra.runtime.registry.IRegistryView; -import tools.refinery.viatra.runtime.util.ViatraQueryLoggingUtil; - -/** - * An abstract {@link IRegistryView} implementation that stores the registry, the set of listeners added to the view and - * the FQN to entry map of the view itself. The only responsibility of subclasses is to decide whether an entry received - * as an addition or removal notification is relevant to the view. - * - * @author Abel Hegedus - * @since 1.3 - */ -public abstract class AbstractRegistryView implements IRegistryView { - - private static final String LISTENER_EXCEPTION_REMOVE = "Exception occurred while notifying view listener %s about entry removal"; - private static final String LISTENER_EXCEPTION_ADD = "Exception occurred while notifying view listener %s about entry addition"; - protected final IQuerySpecificationRegistry registry; - protected final IMultiLookup fqnToEntryMap; - protected final Set listeners; - protected final boolean allowDuplicateFQNs; - - /** - * This method is called both when an addition or removal notification is received from the registry. Subclasses can - * implement view filtering by returning false for those specifications that are not relevant for this view. - * - * @param entry - * that is added or removed in the registry - * @return true if the entry should be added to or removed from the view, false otherwise - */ - protected abstract boolean isEntryRelevant(IQuerySpecificationRegistryEntry entry); - - /** - * Creates a new view instance for the given registry. Note that views are created by the registry and the view - * update mechanisms are also set up by the registry. - * - * @param registry - */ - public AbstractRegistryView(IQuerySpecificationRegistry registry, boolean allowDuplicateFQNs) { - this.registry = registry; - this.allowDuplicateFQNs = allowDuplicateFQNs; - this.fqnToEntryMap = CollectionsFactory.createMultiLookup(Object.class, MemoryType.SETS, Object.class); - this.listeners = new HashSet<>(); - } - - @Override - public IQuerySpecificationRegistry getRegistry() { - return registry; - } - - @Override - public Iterable getEntries() { - return fqnToEntryMap.distinctValuesStream().collect(Collectors.toSet()); - } - - @Override - public Set getQuerySpecificationFQNs() { - return fqnToEntryMap.distinctKeysStream().collect(Collectors.toSet()); - } - - @Override - public boolean hasQuerySpecificationFQN(String fullyQualifiedName) { - Preconditions.checkArgument(fullyQualifiedName != null, "FQN must not be null!"); - return fqnToEntryMap.lookupExists(fullyQualifiedName); - } - - @Override - public Set getEntries(String fullyQualifiedName) { - Preconditions.checkArgument(fullyQualifiedName != null, "FQN must not be null!"); - IMemoryView entries = fqnToEntryMap.lookupOrEmpty(fullyQualifiedName); - return Collections.unmodifiableSet(entries.distinctValues()); - } - - @Override - public void addViewListener(IQuerySpecificationRegistryChangeListener listener) { - Preconditions.checkArgument(listener != null, "Null listener not supported"); - listeners.add(listener); - } - - @Override - public void removeViewListener(IQuerySpecificationRegistryChangeListener listener) { - Preconditions.checkArgument(listener != null, "Null listener not supported"); - listeners.remove(listener); - } - - @Override - public void entryAdded(IQuerySpecificationRegistryEntry entry) { - if (isEntryRelevant(entry)) { - String fullyQualifiedName = entry.getFullyQualifiedName(); - IMemoryView duplicates = fqnToEntryMap.lookup(fullyQualifiedName); - if(!allowDuplicateFQNs && duplicates != null) { - Set removed = new HashSet<>(duplicates.distinctValues()); - for (IQuerySpecificationRegistryEntry e : removed) { - fqnToEntryMap.removePair(fullyQualifiedName, e); - notifyListeners(e, false); - } - } - fqnToEntryMap.addPair(fullyQualifiedName, entry); - notifyListeners(entry, true); - } - } - - @Override - public void entryRemoved(IQuerySpecificationRegistryEntry entry) { - if (isEntryRelevant(entry)) { - String fullyQualifiedName = entry.getFullyQualifiedName(); - fqnToEntryMap.removePair(fullyQualifiedName, entry); - notifyListeners(entry, false); - } - } - - private void notifyListeners(IQuerySpecificationRegistryEntry entry, boolean addition) { - for (IQuerySpecificationRegistryChangeListener listener : listeners) { - try { - if(addition){ - listener.entryAdded(entry); - } else { - listener.entryRemoved(entry); - } - } catch (Exception ex) { - Logger logger = ViatraQueryLoggingUtil.getLogger(AbstractRegistryView.class); - String formatString = addition ? LISTENER_EXCEPTION_ADD : LISTENER_EXCEPTION_REMOVE; - logger.error(String.format(formatString, listener), ex); - } - } - } - -} \ No newline at end of file diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/tabular/EcoreIndexHost.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/tabular/EcoreIndexHost.java deleted file mode 100644 index e87a726a..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/tabular/EcoreIndexHost.java +++ /dev/null @@ -1,166 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.tabular; - -import java.util.Collections; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EClassifier; -import org.eclipse.emf.ecore.EDataType; -import org.eclipse.emf.ecore.EPackage; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.EcorePackage; -import tools.refinery.viatra.runtime.api.scope.QueryScope; -import tools.refinery.viatra.runtime.emf.EMFQueryMetaContext; -import tools.refinery.viatra.runtime.emf.EMFScope; -import tools.refinery.viatra.runtime.emf.types.EClassExactInstancesKey; -import tools.refinery.viatra.runtime.emf.types.EClassTransitiveInstancesKey; -import tools.refinery.viatra.runtime.emf.types.EDataTypeInSlotsKey; -import tools.refinery.viatra.runtime.emf.types.EStructuralFeatureInstancesKey; -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.scopes.IStorageBackend; -import tools.refinery.viatra.runtime.matchers.scopes.SimpleRuntimeContext; -import tools.refinery.viatra.runtime.matchers.scopes.tables.DisjointUnionTable; -import tools.refinery.viatra.runtime.matchers.scopes.tables.ITableWriterBinary; -import tools.refinery.viatra.runtime.matchers.scopes.tables.ITableWriterUnary; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory; - -/** - * Simple EMF-specific demo tabular index host. - * - *

Usage:

    - *
  • First, instantiate index host with given Ecore metamodel packages - *
  • To emulate an EMF instance model, write arbitrary content into the tables using {@link #getTableDirectInstances(EClassifier)} and {@link #getTableFeatureSlots(EStructuralFeature)}. - *
  • Initialize and evaluate regular EMF-based Viatra queries on the scope provided by {@link #getScope()}, as you would on an {@link EMFScope}. - *
      - * - *

      - * EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will - * work or that it will remain the same. - * - * @author Gabor Bergmann - * @since 2.1 - */ -public class EcoreIndexHost extends TabularIndexHost { - - public EcoreIndexHost(IStorageBackend storage, EPackage... packages) { - super(storage, new SimpleRuntimeContext(EMFQueryMetaContext.DEFAULT_SURROGATE)); - - initTables(packages); - } - - @Override - protected boolean isQueryScopeEmulated(Class queryScopeClass) { - return EMFScope.class.equals(queryScopeClass); - } - - - private Map> tableDirectInstances = CollectionsFactory.createMap(); - private Map tableTransitiveInstances = CollectionsFactory.createMap(); - private Map> tableFeatures = CollectionsFactory.createMap(); - - private void initTables(EPackage[] packages) { - - // create instance tables first - for (EPackage ePackage : packages) { - for (EClassifier eClassifier : ePackage.getEClassifiers()) { - boolean unique; - IInputKey classifierKey; - if (eClassifier instanceof EClass) { - EClass eClass = (EClass) eClassifier; - - // create transitive instances table - IInputKey transitiveKey = new EClassTransitiveInstancesKey(eClass); - DisjointUnionTable transitiveTable = registerNewTable(new DisjointUnionTable(transitiveKey, runtimeContext)); - tableTransitiveInstances.put(eClass, transitiveTable); - - // process feature tables - for (EStructuralFeature feature : eClass.getEStructuralFeatures()) { - IInputKey featureKey = new EStructuralFeatureInstancesKey(feature); - ITableWriterBinary.Table featureTable = newBinaryInputTable(featureKey, feature.isUnique()); - tableFeatures.put(feature, featureTable); - } - - // direct instance table - unique = true; - classifierKey = new EClassExactInstancesKey(eClass); - } else { // datatype - unique = false; - classifierKey = new EDataTypeInSlotsKey((EDataType) eClassifier); - } - ITableWriterUnary.Table directTable = newUnaryInputTable(classifierKey, unique); - tableDirectInstances.put(eClassifier, directTable); - } - } - - // global implicit supertype EObject is always available as a transitive table - EClass eObjectClass = EcorePackage.eINSTANCE.getEObject(); - DisjointUnionTable eObjectAllInstancesTable = tableTransitiveInstances.get(eObjectClass); - if (eObjectAllInstancesTable == null) { // is it already added? - IInputKey transitiveKey = new EClassTransitiveInstancesKey(eObjectClass); - eObjectAllInstancesTable = registerNewTable(new DisjointUnionTable(transitiveKey, runtimeContext)); - tableTransitiveInstances.put(eObjectClass, eObjectAllInstancesTable); - - boolean unique = true; - IInputKey classifierKey = new EClassExactInstancesKey(eObjectClass); - ITableWriterUnary.Table directTable = newUnaryInputTable(classifierKey, unique); - tableDirectInstances.put(eObjectClass, directTable); - } - - // set up disjoint unoin tables - for (Entry entry : tableTransitiveInstances.entrySet()) { - EClass eClass = entry.getKey(); - ITableWriterUnary.Table directTable = tableDirectInstances.get(eClass); - - // the direct type itself is a child - entry.getValue().addChildTable(directTable); - - // connect supertypes - for (EClass superClass : eClass.getEAllSuperTypes()) { - DisjointUnionTable transitiveTable = tableTransitiveInstances.get(superClass); - if (transitiveTable == null) { - throw new IllegalStateException( - String.format("No index table found for EClass %s, supertype of %s", - superClass.getName(), eClass.getName()) - ); - } - transitiveTable.addChildTable(directTable); - } - // global implicit supertype - if (!eClass.equals(eObjectClass)) { - eObjectAllInstancesTable.addChildTable(directTable); - } - - } - - } - - public ITableWriterUnary.Table getTableDirectInstances(EClassifier classifier) { - return tableDirectInstances.get(classifier); - } - public ITableWriterBinary.Table getTableFeatureSlots(EStructuralFeature feature) { - return tableFeatures.get(feature); - } - - - - public Set>> getAllCurrentTablesDirectInstances() { - return Collections.unmodifiableSet(tableDirectInstances.entrySet()); - } - public Set>> getAllCurrentTablesFeatures() { - return Collections.unmodifiableSet(tableFeatures.entrySet()); - } - - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/tabular/TabularEngineContext.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/tabular/TabularEngineContext.java deleted file mode 100644 index ee33d3bc..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/tabular/TabularEngineContext.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package tools.refinery.viatra.runtime.tabular; - -import org.apache.log4j.Logger; -import tools.refinery.viatra.runtime.api.ViatraQueryEngine; -import tools.refinery.viatra.runtime.api.scope.*; -import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContext; -import tools.refinery.viatra.runtime.matchers.util.CollectionsFactory; - -import java.lang.reflect.InvocationTargetException; -import java.util.List; -import java.util.concurrent.Callable; - -/** - * @author Gabor Bergmann - * - * @since 2.1 - */ -class TabularEngineContext implements IEngineContext, IBaseIndex { - - private TabularIndexHost indexHost; - private ViatraQueryEngine engine; - private Logger logger; - - private List errorListeners = CollectionsFactory.createObserverList(); - - public TabularEngineContext(TabularIndexHost server, ViatraQueryEngine engine, - IIndexingErrorListener errorListener, Logger logger) { - this.indexHost = server; - this.engine = engine; - this.logger = logger; - - this.addIndexingErrorListener(errorListener); - } - - @Override - public IBaseIndex getBaseIndex() { - return this; - } - - @Override - public void dispose() { - // NOP, server lifecycle not controlled by engine - } - - @Override - public IQueryRuntimeContext getQueryRuntimeContext() { - return indexHost.getRuntimeContext(); - } - - @Override - public V coalesceTraversals(Callable callable) throws InvocationTargetException { - try { - return callable.call(); - } catch (Exception e) { - throw new InvocationTargetException(e); - } - } - - @Override - public void addBaseIndexChangeListener(ViatraBaseIndexChangeListener listener) { - // TODO no notifications yet - } - - @Override - public void removeBaseIndexChangeListener(ViatraBaseIndexChangeListener listener) { - // TODO no notifications yet - } - - @Override - public boolean addInstanceObserver(IInstanceObserver observer, Object observedObject) { - // TODO no notifications yet - return true; - } - - @Override - public boolean removeInstanceObserver(IInstanceObserver observer, Object observedObject) { - // TODO no notifications yet - return true; - } - - @Override - public void resampleDerivedFeatures() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addIndexingErrorListener(IIndexingErrorListener listener) { - return errorListeners.add(listener); - } - - @Override - public boolean removeIndexingErrorListener(IIndexingErrorListener listener) { - return errorListeners.remove(listener); - } - - - -} diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/tabular/TabularIndexHost.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/tabular/TabularIndexHost.java deleted file mode 100644 index 6f2a1f5f..00000000 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/tabular/TabularIndexHost.java +++ /dev/null @@ -1,145 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010-2018, Gabor Bergmann, IncQuery Labs Ltd. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-v20.html. - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -package tools.refinery.viatra.runtime.tabular; - -import tools.refinery.viatra.runtime.api.ViatraQueryEngine; -import tools.refinery.viatra.runtime.api.scope.IEngineContext; -import tools.refinery.viatra.runtime.api.scope.IIndexingErrorListener; -import tools.refinery.viatra.runtime.api.scope.QueryScope; -import tools.refinery.viatra.runtime.matchers.context.IInputKey; -import tools.refinery.viatra.runtime.matchers.scopes.IStorageBackend; -import tools.refinery.viatra.runtime.matchers.scopes.TabularRuntimeContext; -import tools.refinery.viatra.runtime.matchers.scopes.tables.IIndexTable; -import tools.refinery.viatra.runtime.matchers.scopes.tables.ITableWriterBinary; -import tools.refinery.viatra.runtime.matchers.scopes.tables.ITableWriterUnary; - -/** - * Simple tabular index host. - * - * Unlike traditional Viatra instances initialized on a model, - * this index host can be initialized and then queried, - * while its queriable "contents" (base relations) can be separately written using table writer API. - * - *

      Deriving classes are responsible for setting up the tables of this index and providing the writer API to clients. - * For the former, use {@link #newUnaryInputTable(IInputKey, boolean)}, - * {@link #newBinaryInputTable(IInputKey, boolean)} to create input tables, - * or {@link #registerNewTable(IIndexTable)} to register manually created derived tables. - * Instantiate such tables with {@link #runtimeContext} as their table context. - * - * - *

      - * EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will - * work or that it will remain the same. - * - * @see EcoreIndexHost EcoreIndexHost for EMF-specific example usage. - * - * @author Gabor Bergmann - * @since 2.1 - */ -public abstract class TabularIndexHost { - - private final IStorageBackend storage; - protected final TabularRuntimeContext runtimeContext; - protected final TabularIndexScope scope = new TabularIndexScope(); - - public TabularIndexHost(IStorageBackend storage, TabularRuntimeContext runtimeContext) { - this.storage = storage; - this.runtimeContext = runtimeContext; - } - - - public TabularRuntimeContext getRuntimeContext() { - return runtimeContext; - } - - public TabularIndexScope getScope() { - return scope; - } - - /** - * @return true if this index host aims to serve queries that have a scope of the given type - */ - protected abstract boolean isQueryScopeEmulated(Class queryScopeClass); - - - - /** - * Marks the beginning of an update transaction. - * In transaction mode, index table updates may be temporarily delayed for better performance. - * Stateful query backends will not update their results during the index update transaction. (TODO actually achieve this) - */ - public void startUpdateTransaction() { - storage.startTransaction(); - } - /** - * Marks the end of an update transaction. - * Any updates to index tables that were delayed during the transaction must now be flushed. - * Afterwards, stateful query backends will update their results. (TODO actually achieve this) - */ - public void finishUpdateTransaction() { - storage.finishTransaction(); - } - - /** - * To be called by deriving class. Creates and registers a new unary input table. - */ - protected ITableWriterUnary.Table newUnaryInputTable(IInputKey key, boolean unique) { - return registerNewTable(storage.createUnaryTable(key, runtimeContext, unique)); - } - /** - * To be called by deriving class. Creates and registers a new binary input table. - */ - protected ITableWriterBinary.Table newBinaryInputTable(IInputKey key, boolean unique) { - return registerNewTable(storage.createBinaryTable(key, runtimeContext, unique)); - } - /** - * To be called by deriving class. Registers the given freshly created table and also returns it for convenience. - */ - protected Table registerNewTable(Table newTable) { - runtimeContext.registerIndexTable(newTable); - return newTable; - } - - - /** - * A scope describing queries evaluated against tzhis index host. - * @author Gabor Bergmann - * - */ - public class TabularIndexScope extends QueryScope { - - public TabularIndexHost getIndexHost() { - return TabularIndexHost.this; - } - - @Override - public int hashCode() { - return getIndexHost().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof TabularIndexScope) - return getIndexHost().equals(((TabularIndexScope) obj).getIndexHost()); - return false; - } - - @Override - public boolean isCompatibleWithQueryScope(Class queryScopeClass) { - return isQueryScopeEmulated(queryScopeClass) || super.isCompatibleWithQueryScope(queryScopeClass); - } - - @Override - protected IEngineContext createEngineContext(ViatraQueryEngine engine, IIndexingErrorListener errorListener, org.apache.log4j.Logger logger) { - return new TabularEngineContext(getIndexHost(), engine, errorListener, logger); - } - - } -} -- cgit v1.2.3-54-g00ecf