1
16
17 package gate.util;
18
19 import java.net.MalformedURLException;
20 import java.net.URL;
21 import java.util.Set;
22 import java.util.Vector;
23
24 import com.ontotext.gate.ontology.OntologyImpl;
25
26 import gate.FeatureMap;
27 import gate.creole.ontology.Taxonomy;
28 import gate.event.FeatureMapListener;
29
30
31
35 public class SimpleFeatureMapImpl
37 extends SimpleMapImpl
38 implements FeatureMap, java.io.Serializable, java.lang.Cloneable,
40 gate.creole.ANNIEConstants
41 {
43
44 private static final boolean DEBUG = false;
45
46
47
48 static final long serialVersionUID = -2747241616127229116L;
49
50
69 public boolean subsumes(FeatureMap aFeatureMap){
70 if (aFeatureMap == null) return true;
72
73 if (this.size() < aFeatureMap.size()) return false;
74
75 SimpleFeatureMapImpl sfm = (SimpleFeatureMapImpl)aFeatureMap;
76
77 Object key;
78 Object keyValueFromAFeatureMap;
79 Object keyValueFromThis;
80
81 for (int i = 0; i < sfm.count; i++) {
82 key = sfm.theKeys[i];
83 keyValueFromAFeatureMap = sfm.theValues[i];
84 int v = super.getSubsumeKey(key);
85 if (v < 0) return false;
86 keyValueFromThis = theValues[v];
88 if ( (keyValueFromThis == null && keyValueFromAFeatureMap != null) ||
89 (keyValueFromThis != null && keyValueFromAFeatureMap == null)
90 ) return false;
91
92
94 if ((keyValueFromThis != null) && (keyValueFromAFeatureMap != null)) {
95
96 if ( key.equals(LOOKUP_CLASS_FEATURE_NAME) ) {
97
98 Object sfmOntoObj = sfm.get(LOOKUP_ONTOLOGY_FEATURE_NAME);
99 Object thisOntoObj = this.get(LOOKUP_ONTOLOGY_FEATURE_NAME);
100 if (null!=sfmOntoObj && null!= thisOntoObj) {
101 if (sfmOntoObj.equals(thisOntoObj)) {
102 boolean doSubsume = ontologySubsume(
103 sfmOntoObj.toString(),
104 keyValueFromAFeatureMap.toString(),
105 keyValueFromThis.toString());
106 if (!doSubsume ) {
107 return false;
108 }
109 } } else {
112 return false;
114 }
115 } else {
116
117 if (!keyValueFromThis.equals(keyValueFromAFeatureMap)) return false;
118 }
120 } }
123 return true;
124 }
126
135 public boolean subsumes(Taxonomy ontologyLR, FeatureMap aFeatureMap) {
136
137 if (ontologyLR == null) {
138 return this.subsumes(aFeatureMap);
139 }
140
141 if (aFeatureMap == null)
142 return true;
143
144 if (this.size() < aFeatureMap.size())
145 return false;
146
147 SimpleFeatureMapImpl sfm = (SimpleFeatureMapImpl) aFeatureMap;
148
149 Object key;
150 Object keyValueFromAFeatureMap;
151 Object keyValueFromThis;
152
153 for (int i = 0; i < sfm.count; i++) {
154 key = sfm.theKeys[i];
155 keyValueFromAFeatureMap = sfm.theValues[i];
156 int v = super.getSubsumeKey(key);
157 if (v < 0)
158 return false;
159 keyValueFromThis = theValues[v];
161 if ( (keyValueFromThis == null && keyValueFromAFeatureMap != null) ||
162 (keyValueFromThis != null && keyValueFromAFeatureMap == null)
163 )
164 return false;
165
166
168 if ( (keyValueFromThis != null) && (keyValueFromAFeatureMap != null)) {
169
170 if (key.equals(LOOKUP_CLASS_FEATURE_NAME)) {
171
173 try {
174
175 if (DEBUG) {
176 Out.prln("\nClass in rule: " + keyValueFromAFeatureMap.toString());
177 Out.prln("\nClass in annotation: " + keyValueFromThis.toString());
178 Out.prln("\nisSubClassOf: " +
179 ontologyLR.isSubClassOf(keyValueFromAFeatureMap.toString(),
180 keyValueFromThis.toString()));
181 }
182
183 return ontologyLR.isSubClassOf(keyValueFromAFeatureMap.toString(),
184 keyValueFromThis.toString());
185 } catch (Exception ex) {
186 throw new gate.util.GateRuntimeException(ex);
187 }
188 }
189 else {
190
191 if (!keyValueFromThis.equals(keyValueFromAFeatureMap))
192 return false;
193 }
195 } }
198 return true;
199 }
201
202
225 public boolean subsumes(FeatureMap aFeatureMap, Set aFeatureNamesSet){
226 if (aFeatureNamesSet == null) return this.subsumes(aFeatureMap);
228 if (aFeatureMap == null) return true;
230 if (aFeatureNamesSet.isEmpty()) return true;
232
233 SimpleFeatureMapImpl sfm = (SimpleFeatureMapImpl)aFeatureMap;
234
235 Object key;
236 Object keyValueFromAFeatureMap;
237 Object keyValueFromThis;
238
239 for (int i = 0; i < sfm.count; i++) {
240 key = sfm.theKeys[i];
241
242 if (!aFeatureNamesSet.contains(key))
243 continue;
244
245 keyValueFromAFeatureMap = sfm.theValues[i];
246 keyValueFromThis = get(key);
247
248 if ( (keyValueFromThis == null && keyValueFromAFeatureMap != null) ||
249 (keyValueFromThis != null && keyValueFromAFeatureMap == null)
250 ) return false;
251
252 if ((keyValueFromThis != null) && (keyValueFromAFeatureMap != null)) {
253 if ( key.equals(LOOKUP_CLASS_FEATURE_NAME) ) {
254
255 if (!aFeatureNamesSet.contains(LOOKUP_ONTOLOGY_FEATURE_NAME))
256 continue;
257
258 Object sfmOntoObj = sfm.get(LOOKUP_ONTOLOGY_FEATURE_NAME);
259 Object thisOntoObj = this.get(LOOKUP_ONTOLOGY_FEATURE_NAME);
260 if (null!=sfmOntoObj && null!= thisOntoObj) {
261 if (sfmOntoObj.equals(thisOntoObj)) {
262 if (! ontologySubsume(
263 sfmOntoObj.toString(),
264 keyValueFromAFeatureMap.toString(),
265 keyValueFromThis.toString()))
266 return false;
267 } } else {
270 return false;
272 }
273 } else {
274
275 if (!keyValueFromThis.equals(keyValueFromAFeatureMap)) return false;
276 } } }
280 return true;
281 }
283
284
288 public Object put(Object key, Object value) {
289 Object result = super.put(key, value);
290 this.fireMapUpdatedEvent();
291 return result;
292 }
294
298 public Object remove(Object key) {
299 Object result = super.remove(key);
300 this.fireMapUpdatedEvent();
301 return result;
302 }
304 public void clear() {
305 super.clear();
306 this.fireMapUpdatedEvent();
308 }
310 public Object clone() {
312 return super.clone();
313 }
315 public boolean equals(Object o) {
316 return super.equals(o);
317 }
319 private transient Vector mapListeners;
323
326 public synchronized void removeFeatureMapListener(FeatureMapListener l) {
327 if (mapListeners != null && mapListeners.contains(l)) {
328 Vector v = (Vector) mapListeners.clone();
329 v.removeElement(l);
330 mapListeners = v;
331 }
332 }
336 public synchronized void addFeatureMapListener(FeatureMapListener l) {
337 Vector v = mapListeners == null ? new Vector(2) : (Vector)mapListeners.clone();
338 if (!v.contains(l)) {
339 v.addElement(l);
340 mapListeners = v;
341 }
342 }
344
347 protected void fireMapUpdatedEvent () {
348 if (mapListeners != null) {
349 Vector listeners = mapListeners;
350 int count = listeners.size();
351 if (count == 0) return;
352 for (int i = 0; i < count; i++)
353 ((FeatureMapListener) listeners.elementAt(i)).featureMapUpdated();
354 }
355 }
357
358
361 protected boolean ontologySubsume(String ontoUrl,String value1,String value2) {
362 boolean result = false;
363 try {
364 URL url;
365 try {
366 url = new URL(ontoUrl);
367 } catch (MalformedURLException e){
368 throw new RuntimeException(
369 "\nin SimpleFeatureMapImpl on ontologySubsume()\n"
370 +e.getMessage()+"\n");
371 }
372
373
377 Taxonomy o = new OntologyImpl().getOntology(url);
378
379 result = o.isSubClassOf(value1, value2);
380
381 } catch (gate.creole.ResourceInstantiationException x) {
382 x.printStackTrace(Err.getPrintWriter());
383 }
384 return result;
385 }
387 }
389