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
56 public boolean subsumes(FeatureMap aFeatureMap){
57 if (aFeatureMap == null) return true;
59
60 if (this.size() < aFeatureMap.size()) return false;
61
62 SimpleFeatureMapImpl sfm = (SimpleFeatureMapImpl)aFeatureMap;
63
64 Object key;
65 Object keyValueFromAFeatureMap;
66 Object keyValueFromThis;
67
68 for (int i = 0; i < sfm.count; i++) {
69 key = sfm.theKeys[i];
70 keyValueFromAFeatureMap = sfm.theValues[i];
71 int v = super.getSubsumeKey(key);
72 if (v < 0) return false;
73 keyValueFromThis = theValues[v];
75 if ( (keyValueFromThis == null && keyValueFromAFeatureMap != null) ||
76 (keyValueFromThis != null && keyValueFromAFeatureMap == null)
77 ) return false;
78
79
81 if ((keyValueFromThis != null) && (keyValueFromAFeatureMap != null)) {
82
83 if ( key.equals(LOOKUP_CLASS_FEATURE_NAME) ) {
84
85 Object sfmOntoObj = sfm.get(LOOKUP_ONTOLOGY_FEATURE_NAME);
86 Object thisOntoObj = this.get(LOOKUP_ONTOLOGY_FEATURE_NAME);
87 if (null!=sfmOntoObj && null!= thisOntoObj) {
88 if (sfmOntoObj.equals(thisOntoObj)) {
89 boolean doSubsume = ontologySubsume(
90 sfmOntoObj.toString(),
91 keyValueFromAFeatureMap.toString(),
92 keyValueFromThis.toString());
93 if (!doSubsume ) {
94 return false;
95 }
96 } } else {
99 return false;
101 }
102 } else {
103
104 if (!keyValueFromThis.equals(keyValueFromAFeatureMap)) return false;
105 }
107 } }
110 return true;
111 }
113
122 public boolean subsumes(Taxonomy ontologyLR, FeatureMap aFeatureMap) {
123
124 if (ontologyLR == null) {
125 return this.subsumes(aFeatureMap);
126 }
127
128 if (aFeatureMap == null)
129 return true;
130
131 if (this.size() < aFeatureMap.size())
132 return false;
133
134 SimpleFeatureMapImpl sfm = (SimpleFeatureMapImpl) aFeatureMap;
135
136 Object key;
137 Object keyValueFromAFeatureMap;
138 Object keyValueFromThis;
139
140 for (int i = 0; i < sfm.count; i++) {
141 key = sfm.theKeys[i];
142 keyValueFromAFeatureMap = sfm.theValues[i];
143 int v = super.getSubsumeKey(key);
144 if (v < 0)
145 return false;
146 keyValueFromThis = theValues[v];
148 if ( (keyValueFromThis == null && keyValueFromAFeatureMap != null) ||
149 (keyValueFromThis != null && keyValueFromAFeatureMap == null)
150 )
151 return false;
152
153
155 if ( (keyValueFromThis != null) && (keyValueFromAFeatureMap != null)) {
156
157 if (key.equals(LOOKUP_CLASS_FEATURE_NAME)) {
158
160 try {
161
162 if (DEBUG) {
163 Out.prln("\nClass in rule: " + keyValueFromAFeatureMap.toString());
164 Out.prln("\nClass in annotation: " + keyValueFromThis.toString());
165 Out.prln("\nisSubClassOf: " +
166 ontologyLR.isSubClassOf(keyValueFromAFeatureMap.toString(),
167 keyValueFromThis.toString()));
168 }
169
170 return ontologyLR.isSubClassOf(keyValueFromAFeatureMap.toString(),
171 keyValueFromThis.toString());
172 } catch (Exception ex) {
173 throw new gate.util.GateRuntimeException(ex);
174 }
175 }
176 else {
177
178 if (!keyValueFromThis.equals(keyValueFromAFeatureMap))
179 return false;
180 }
182 } }
185 return true;
186 }
188
189
200 public boolean subsumes(FeatureMap aFeatureMap, Set aFeatureNamesSet){
201 if (aFeatureNamesSet == null) return this.subsumes(aFeatureMap);
203 if (aFeatureMap == null) return true;
205 if (aFeatureNamesSet.isEmpty()) return true;
207
208 SimpleFeatureMapImpl sfm = (SimpleFeatureMapImpl)aFeatureMap;
209
210 Object key;
211 Object keyValueFromAFeatureMap;
212 Object keyValueFromThis;
213
214 for (int i = 0; i < sfm.count; i++) {
215 key = sfm.theKeys[i];
216
217 if (!aFeatureNamesSet.contains(key))
218 continue;
219
220 keyValueFromAFeatureMap = sfm.theValues[i];
221 keyValueFromThis = get(key);
222
223 if ( (keyValueFromThis == null && keyValueFromAFeatureMap != null) ||
224 (keyValueFromThis != null && keyValueFromAFeatureMap == null)
225 ) return false;
226
227 if ((keyValueFromThis != null) && (keyValueFromAFeatureMap != null)) {
228 if ( key.equals(LOOKUP_CLASS_FEATURE_NAME) ) {
229
230 if (!aFeatureNamesSet.contains(LOOKUP_ONTOLOGY_FEATURE_NAME))
231 continue;
232
233 Object sfmOntoObj = sfm.get(LOOKUP_ONTOLOGY_FEATURE_NAME);
234 Object thisOntoObj = this.get(LOOKUP_ONTOLOGY_FEATURE_NAME);
235 if (null!=sfmOntoObj && null!= thisOntoObj) {
236 if (sfmOntoObj.equals(thisOntoObj)) {
237 if (! ontologySubsume(
238 sfmOntoObj.toString(),
239 keyValueFromAFeatureMap.toString(),
240 keyValueFromThis.toString()))
241 return false;
242 } } else {
245 return false;
247 }
248 } else {
249
250 if (!keyValueFromThis.equals(keyValueFromAFeatureMap)) return false;
251 } } }
255 return true;
256 }
258
259
263 public Object put(Object key, Object value) {
264 Object result = super.put(key, value);
265 this.fireMapUpdatedEvent();
266 return result;
267 }
269
273 public Object remove(Object key) {
274 Object result = super.remove(key);
275 this.fireMapUpdatedEvent();
276 return result;
277 }
279 public void clear() {
280 super.clear();
281 this.fireMapUpdatedEvent();
283 }
285 public Object clone() {
287 return super.clone();
288 }
290 public boolean equals(Object o) {
291 return super.equals(o);
292 }
294 private transient Vector mapListeners;
298
301 public synchronized void removeFeatureMapListener(FeatureMapListener l) {
302 if (mapListeners != null && mapListeners.contains(l)) {
303 Vector v = (Vector) mapListeners.clone();
304 v.removeElement(l);
305 mapListeners = v;
306 }
307 }
311 public synchronized void addFeatureMapListener(FeatureMapListener l) {
312 Vector v = mapListeners == null ? new Vector(2) : (Vector)mapListeners.clone();
313 if (!v.contains(l)) {
314 v.addElement(l);
315 mapListeners = v;
316 }
317 }
319
322 protected void fireMapUpdatedEvent () {
323 if (mapListeners != null) {
324 Vector listeners = mapListeners;
325 int count = listeners.size();
326 if (count == 0) return;
327 for (int i = 0; i < count; i++)
328 ((FeatureMapListener) listeners.elementAt(i)).featureMapUpdated();
329 }
330 }
332
333
336 protected boolean ontologySubsume(String ontoUrl,String value1,String value2) {
337 boolean result = false;
338 try {
339 URL url;
340 try {
341 url = new URL(ontoUrl);
342 } catch (MalformedURLException e){
343 throw new RuntimeException(
344 "\nin SimpleFeatureMapImpl on ontologySubsume()\n"
345 +e.getMessage()+"\n");
346 }
347
348
352 Taxonomy o = new OntologyImpl().getOntology(url);
353
354 result = o.isSubClassOf(value1, value2);
355
356 } catch (gate.creole.ResourceInstantiationException x) {
357 x.printStackTrace(Err.getPrintWriter());
358 } catch (gate.creole.ontology.NoSuchClosureTypeException clex) {
359 clex.printStackTrace(Err.getPrintWriter());
360 }
361 return result;
362 }
364 }
366