This repository has been archived by the owner on Jan 12, 2022. It is now read-only.
/
PatternRegistry.java
295 lines (266 loc) · 10.4 KB
/
PatternRegistry.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
/*******************************************************************************
* Copyright (c) 2010-2012, Zoltan Ujhelyi, Tamas Szabo, Istvan Rath and Daniel Varro
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Zoltan Ujhelyi, Tamas Szabo - initial API and implementation
*******************************************************************************/
package org.eclipse.incquery.tooling.ui.queryexplorer.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.incquery.patternlanguage.emf.eMFPatternLanguage.PatternModel;
import org.eclipse.incquery.patternlanguage.helper.CorePatternLanguageHelper;
import org.eclipse.incquery.patternlanguage.patternLanguage.Pattern;
import org.eclipse.incquery.runtime.exception.IncQueryException;
import org.eclipse.incquery.tooling.ui.IncQueryGUIPlugin;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.ui.PlatformUI;
/**
* Utility class used by the Query Explorer for the maintenance of registered patterns.
*
* @author Tamas Szabo
*
*/
public class PatternRegistry {
private static PatternRegistry instance;
// maps the eiq files to the list of patterns which were registered from that file
private final Map<IFile, List<Pattern>> registeredPatterModels;
private final List<Pattern> activePatterns;
private final Map<String, Pattern> patternNameMap;
private final ILog logger = IncQueryGUIPlugin.getDefault().getLog();
public static synchronized PatternRegistry getInstance() {
if (instance == null) {
instance = new PatternRegistry();
}
return instance;
}
protected PatternRegistry() {
registeredPatterModels = new HashMap<IFile, List<Pattern>>();
patternNameMap = new HashMap<String, Pattern>();
activePatterns = new ArrayList<Pattern>();
}
public void addGeneratedPattern(Pattern pattern, String patternFqn) {
this.patternNameMap.put(patternFqn, pattern);
}
public boolean isGenerated(Pattern pattern) {
return DatabindingUtil.getGeneratedPatterns().contains(pattern);
}
/**
* Unregisters the given pattern from the registry.
*
* @param pattern the pattern instance to be unregistered
*/
public void unregisterPattern(Pattern pattern) {
String patternFqn = CorePatternLanguageHelper.getFullyQualifiedName(pattern);
patternNameMap.remove(patternFqn);
}
/**
* Registers the patterns within the given (parsed) pattern model.
*
* @param file
* the eiq file instance
* @param patternModel
* the parsed pattern model
* @return the list of patterns registered
*/
public List<Pattern> registerPatternModel(IFile file, PatternModel patternModel) {
List<Pattern> newPatterns = new ArrayList<Pattern>();
if (patternModel != null) {
List<IStatus> warnings = new ArrayList<IStatus>();
for (Pattern pattern : patternModel.getPatterns()) {
String patternFqn = CorePatternLanguageHelper.getFullyQualifiedName(pattern);
if (!patternNameMap.containsKey(patternFqn)) {
Boolean annotationValue = DatabindingUtil.getValueOfQueryExplorerAnnotation(pattern);
if (!(annotationValue != null && !annotationValue)) {
patternNameMap.put(patternFqn, pattern);
newPatterns.add(pattern);
activePatterns.add(pattern);
}
} else {
String message = "A pattern with the fully qualified name '" + patternFqn
+ "' already exists in the pattern registry.";
IncQueryException incQueryException = new IncQueryException(message,
"Duplicate qualified name of pattern");
IStatus status = new Status(IStatus.WARNING, IncQueryGUIPlugin.PLUGIN_ID, message,
incQueryException);
logger.log(status);
warnings.add(status);
}
}
if (!warnings.isEmpty()) {
if (warnings.size() == 1) {
ErrorDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), null,
"Warning during pattern registration", warnings.get(0));
} else {
MultiStatus multiStatus = new MultiStatus(
IncQueryGUIPlugin.PLUGIN_ID,
IStatus.WARNING,
warnings.toArray(new IStatus[0]),
"Multiple patterns with matching fully qualified names already exist in the pattern registry.",
null);
ErrorDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), null,
"Warning during pattern registration", multiStatus);
}
}
}
if (!newPatterns.isEmpty()) {
this.registeredPatterModels.put(file, newPatterns);
}
return Collections.unmodifiableList(newPatterns);
}
/**
* Sets the given pattern as active.
*
* @param p
* the pattern instance
*/
public void addActivePattern(Pattern p) {
// list must be used to retain ordering but duplicate elements are not allowed
if (!activePatterns.contains(p)) {
activePatterns.add(p);
}
}
/**
* Returns the (unmodifiable) list of registered patterns from the given file.
*
* @param file
* the eiq file instance
* @return the list of patterns registered
*/
public List<Pattern> getRegisteredPatternsForFile(IFile file) {
final List<Pattern> list = registeredPatterModels.get(file);
return list == null ? Collections.<Pattern> emptyList() : Collections.unmodifiableList(list);
}
/**
* Returns true if there are no (generic) patterns registered, false otherwise.
*
* @return
*/
public boolean isEmpty() {
return registeredPatterModels.isEmpty();
}
/**
* Unregisters the patterns within the given eiq file and returns the list of those patterns that were currently
* active from the given file.
*
* @param file
* the eiq file instance
* @return the list of removed patterns
*/
public List<Pattern> unregisterPatternModel(IFile file) {
List<Pattern> removedPatterns = new ArrayList<Pattern>();
List<Pattern> patterns = this.registeredPatterModels.remove(file);
if (patterns != null) {
for (Pattern p : patterns) {
String patternFqn = CorePatternLanguageHelper.getFullyQualifiedName(p);
if (activePatterns.remove(p)) {
removedPatterns.add(p);
}
patternNameMap.remove(patternFqn);
}
}
return Collections.unmodifiableList(removedPatterns);
}
/**
* Sets the given pattern as passive.
*
* @param p
* the pattern instance
*/
public void removeActivePattern(Pattern p) {
activePatterns.remove(p);
}
/**
* Returns the pattern associated with the given fully qualified name.
*
* @param patternFqn
* the fqn of the pattern
* @return the pattern instance
*/
public Pattern getPatternByFqn(String patternFqn) {
return patternNameMap.get(patternFqn);
}
/**
* Returns the list of active patterns.
*
* @return the list of active patterns
*/
public List<Pattern> getActivePatterns() {
// Must return a new copy of the active patterns list
return new ArrayList<Pattern>(activePatterns);
}
/**
* Returns true if the given pattern is currently active, false otherwise.
*
* @param patternFqn
* the fqn of the pattern
* @return true if the pattern is active, false otherwise
*/
public boolean isActive(String patternFqn) {
for (Pattern p : activePatterns) {
if (CorePatternLanguageHelper.getFullyQualifiedName(p).matches(patternFqn)) {
return true;
}
}
return false;
}
/**
* Returns the names of the patterns registered in the registry.
*
* @return the list of names of the patterns
*/
public Collection<String> getPatternNames() {
return Collections.unmodifiableCollection(patternNameMap.keySet());
}
/**
* Returns the list of (generic) patterns registered in the registry.
*
* @return the list of (generic) patterns registered
*/
public List<Pattern> getPatterns() {
List<Pattern> patterns = new ArrayList<Pattern>();
for (List<Pattern> pm : registeredPatterModels.values()) {
patterns.addAll(pm);
}
return Collections.unmodifiableList(patterns);
}
/**
* Returns the list of eiq files from which patterns are registered.
*
* @return the list of eiq files
*/
public Collection<IFile> getFiles() {
return Collections.unmodifiableCollection(registeredPatterModels.keySet());
}
/**
* Returns the eiq file instance that the given pattern can be found in.
*
* @param pattern
* the pattern instance
* @return the eiq file
*/
public IFile getFileForPattern(Pattern pattern) {
if (pattern != null && patternNameMap.containsValue(pattern)) {
for (Entry<IFile, List<Pattern>> entry : registeredPatterModels.entrySet()) {
List<Pattern> patterns = entry.getValue();
if (patterns.size() > 0 && patterns.contains(pattern)) {
return entry.getKey();
}
}
}
return null;
}
}