aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/QuerySpecificationRegistryImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/QuerySpecificationRegistryImpl.java')
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/QuerySpecificationRegistryImpl.java177
1 files changed, 177 insertions, 0 deletions
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
new file mode 100644
index 00000000..63306e93
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/registry/impl/QuerySpecificationRegistryImpl.java
@@ -0,0 +1,177 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Abel Hegedus, IncQuery Labs Ltd.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package tools.refinery.viatra.runtime.registry.impl;
10
11import static tools.refinery.viatra.runtime.matchers.util.Preconditions.checkArgument;
12
13import java.util.Map;
14
15import org.apache.log4j.Logger;
16import tools.refinery.viatra.runtime.extensibility.IQuerySpecificationProvider;
17import tools.refinery.viatra.runtime.registry.IConnectorListener;
18import tools.refinery.viatra.runtime.registry.IDefaultRegistryView;
19import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistry;
20import tools.refinery.viatra.runtime.registry.IRegistryView;
21import tools.refinery.viatra.runtime.registry.IRegistryViewFactory;
22import tools.refinery.viatra.runtime.registry.IRegistryViewFilter;
23import tools.refinery.viatra.runtime.registry.IQuerySpecificationRegistryChangeListener;
24import tools.refinery.viatra.runtime.registry.IRegistrySourceConnector;
25import tools.refinery.viatra.runtime.registry.data.QuerySpecificationStore;
26import tools.refinery.viatra.runtime.registry.data.RegistryEntryImpl;
27import tools.refinery.viatra.runtime.registry.data.RegistrySourceImpl;
28import tools.refinery.viatra.runtime.util.ViatraQueryLoggingUtil;
29
30/**
31 * This is the default implementation of the {@link IQuerySpecificationRegistry} interface.
32 * It uses a {@link QuerySpecificationStore} to keep track of sources and entries.
33 * It uses a {@link RegistryChangeMultiplexer} to update all views and a single {@link IConnectorListener}
34 * to subscribe to sources added to the registry.
35 *
36 * @author Abel Hegedus
37 *
38 */
39public class QuerySpecificationRegistryImpl implements IQuerySpecificationRegistry {
40
41 private static final String CONNECTOR_NULL_MSG = "Connector cannot be null";
42 private final QuerySpecificationStore querySpecificationStore;
43 private final IConnectorListener connectorListener;
44 private final RegistryChangeMultiplexer multiplexer;
45 private final Logger logger;
46 private IDefaultRegistryView defaultView = null;
47
48 /**
49 * Creates a new instance of the registry
50 */
51 public QuerySpecificationRegistryImpl() {
52 this.querySpecificationStore = new QuerySpecificationStore();
53 this.connectorListener = new RegistryUpdaterConnectorListener();
54 this.multiplexer = new RegistryChangeMultiplexer();
55 this.logger = ViatraQueryLoggingUtil.getLogger(IQuerySpecificationRegistry.class);
56 }
57
58 @Override
59 public boolean addSource(IRegistrySourceConnector connector) {
60 checkArgument(connector != null, CONNECTOR_NULL_MSG);
61 String identifier = connector.getIdentifier();
62 Map<String, RegistrySourceImpl> sources = querySpecificationStore.getSources();
63 if(sources.containsKey(identifier)){
64 return false;
65 }
66 RegistrySourceImpl source = new RegistrySourceImpl(identifier, querySpecificationStore, connector.includeSpecificationsInDefaultViews());
67 sources.put(identifier, source);
68 connector.addListener(connectorListener);
69 logger.debug("Source added: " + source.getIdentifier());
70 return true;
71 }
72
73 @Override
74 public boolean removeSource(IRegistrySourceConnector connector) {
75 checkArgument(connector != null, CONNECTOR_NULL_MSG);
76 String identifier = connector.getIdentifier();
77 Map<String, RegistrySourceImpl> sources = querySpecificationStore.getSources();
78 if(!sources.containsKey(identifier)){
79 return false;
80 }
81 connector.removeListener(connectorListener);
82 RegistrySourceImpl source = sources.remove(identifier);
83 for (RegistryEntryImpl entry : source.getFqnToEntryMap().values()) {
84 multiplexer.entryRemoved(entry);
85 }
86 logger.debug("Source removed: " + source.getIdentifier());
87 return true;
88 }
89
90 /**
91 * @return the internal store of the registry
92 */
93 protected QuerySpecificationStore getStore() {
94 return querySpecificationStore;
95 }
96
97 @Override
98 public IRegistryView createView() {
99 return createGlobalView();
100 }
101
102 private GlobalRegistryView createGlobalView() {
103 GlobalRegistryView registryView = new GlobalRegistryView(this);
104 initializeChangeListener(registryView);
105 return registryView;
106 }
107
108 protected void initializeChangeListener(IQuerySpecificationRegistryChangeListener listener) {
109 // send existing entries to aspect
110 for (RegistrySourceImpl source : querySpecificationStore.getSources().values()) {
111 Map<String, RegistryEntryImpl> entryMap = source.getFqnToEntryMap();
112 for (RegistryEntryImpl entry : entryMap.values()) {
113 listener.entryAdded(entry);
114 }
115 }
116 multiplexer.addListener(listener);
117 }
118
119 @Override
120 public IRegistryView createView(IRegistryViewFilter filter) {
121 checkArgument(filter != null, "Filter cannot be null");
122 FilteringRegistryView registryView = new FilteringRegistryView(this, filter, false);
123 initializeChangeListener(registryView);
124 return registryView;
125 }
126
127 /**
128 * Internal connector listener implementation for updating internal store and propagating changes to views.
129 *
130 * @author Abel Hegedus
131 *
132 */
133 private final class RegistryUpdaterConnectorListener implements IConnectorListener {
134 @Override
135 public void querySpecificationAdded(IRegistrySourceConnector connector, IQuerySpecificationProvider specification) {
136 String identifier = connector.getIdentifier();
137 RegistrySourceImpl source = querySpecificationStore.getSources().get(identifier);
138 String fullyQualifiedName = specification.getFullyQualifiedName();
139 RegistryEntryImpl registryEntry = new RegistryEntryImpl(source, specification);
140 RegistryEntryImpl oldEntry = source.getFqnToEntryMap().put(fullyQualifiedName, registryEntry);
141 if(oldEntry != null) {
142 logger.warn(String.format("Specification added with existing FQN %s in source %s", fullyQualifiedName, identifier));
143 multiplexer.entryRemoved(oldEntry);
144 }
145 multiplexer.entryAdded(registryEntry);
146
147 }
148
149 @Override
150 public void querySpecificationRemoved(IRegistrySourceConnector connector, IQuerySpecificationProvider specification) {
151 String identifier = connector.getIdentifier();
152 RegistrySourceImpl source = querySpecificationStore.getSources().get(identifier);
153 String fullyQualifiedName = specification.getFullyQualifiedName();
154 RegistryEntryImpl registryEntry = source.getFqnToEntryMap().remove(fullyQualifiedName);
155 if(registryEntry != null) {
156 multiplexer.entryRemoved(registryEntry);
157 }
158 }
159 }
160
161 @Override
162 public IDefaultRegistryView getDefaultView() {
163 if(this.defaultView == null){
164 this.defaultView = createGlobalView();
165 }
166 return this.defaultView;
167 }
168
169 @Override
170 public IRegistryView createView(IRegistryViewFactory factory) {
171 IRegistryView registryView = factory.createView(this);
172 initializeChangeListener(registryView);
173 return registryView;
174 }
175
176
177}