|
DatabaseAnnotationSetImpl |
|
1 /* 2 * Copyright (c) 1998-2001, The University of Sheffield. 3 * 4 * This file is part of GATE (see http://gate.ac.uk/), and is free 5 * software, licenced under the GNU Library General Public License, 6 * Version 2, June 1991 (in the distribution as file licence.html, 7 * and also available at http://gate.ac.uk/gate/licence.html). 8 * 9 * Kalina Bontcheva 21/10/2001 10 * 11 * $Id: DatabaseAnnotationSetImpl.java,v 1.14 2002/07/12 13:25:57 valyt Exp $ 12 */ 13 14 package gate.annotation; 15 16 import java.util.*; 17 18 import junit.framework.*; 19 20 import gate.event.*; 21 import gate.*; 22 import gate.util.*; 23 import gate.corpora.*; 24 //import gate.persist.*; 25 26 27 public class DatabaseAnnotationSetImpl extends AnnotationSetImpl 28 implements DatastoreListener, 29 EventAwareAnnotationSet, 30 AnnotationListener { 31 32 /** 33 * The listener for the events coming from the document (annotations and 34 * annotation sets added or removed). 35 */ 36 //= protected EventsHandler eventHandler; 37 38 protected HashSet addedAnnotations = new HashSet(); 39 protected HashSet removedAnnotations = new HashSet(); 40 protected HashSet updatedAnnotations = new HashSet(); 41 42 private boolean validating = false; 43 44 public void assertValid() { 45 46 if (validating) 47 return; 48 49 validating = true; 50 //avoid recursion 51 52 //doc can't be null 53 Assert.assertNotNull(this.doc); 54 //doc.assertValid(); 55 56 validating = false; 57 } 58 59 /** Construction from Document. */ 60 public DatabaseAnnotationSetImpl(Document doc) { 61 62 super(doc); 63 64 //preconditions 65 Assert.assertTrue(doc instanceof DatabaseDocumentImpl); 66 67 //= eventHandler = new EventsHandler(); 68 //= this.addAnnotationSetListener(eventHandler); 69 70 //add self as listener for sync events from the document's datastore 71 //00 doc.getDataStore().removeDatastoreListener(this); 72 doc.getDataStore().addDatastoreListener(this); 73 74 } // construction from document 75 76 /** Construction from Document and name. */ 77 public DatabaseAnnotationSetImpl(Document doc, String name) { 78 super(doc, name); 79 80 //preconditions 81 Assert.assertTrue(doc instanceof DatabaseDocumentImpl); 82 83 //= eventHandler = new EventsHandler(); 84 //= this.addAnnotationSetListener(eventHandler); 85 86 //add self as listener for sync events from the document's datastore 87 //00 doc.getDataStore().removeDatastoreListener(this); 88 doc.getDataStore().addDatastoreListener(this); 89 90 } // construction from document and name 91 92 93 /** Construction from Document and name. */ 94 public DatabaseAnnotationSetImpl(Document doc, Collection c) { 95 this(c); 96 this.doc = (DocumentImpl) doc; 97 //add self as listener for sync events from the document's datastore 98 //00 doc.getDataStore().removeDatastoreListener(this); 99 //00 doc.getDataStore().addDatastoreListener(this); 100 } // construction from document and name 101 102 /** Construction from Document and name. */ 103 public DatabaseAnnotationSetImpl(Document doc, String name, Collection c) { 104 this(doc,c); 105 this.name = name; 106 //add self as listener for sync events from the document's datastore 107 //00 doc.getDataStore().removeDatastoreListener(this); 108 doc.getDataStore().addDatastoreListener(this); 109 } // construction from document and name 110 111 112 /** Construction from Collection (which must be an AnnotationSet) */ 113 public DatabaseAnnotationSetImpl(Collection c) throws ClassCastException { 114 115 super(c); 116 117 //also copy the name, because that super one doesn't 118 AnnotationSet as = (AnnotationSet) c; 119 this.name = as.getName(); 120 121 //= eventHandler = new EventsHandler(); 122 //= this.addAnnotationSetListener(eventHandler); 123 124 Iterator iter = this.iterator(); 125 while(iter.hasNext()) 126 ((Annotation) iter.next()).addAnnotationListener(this); 127 128 Document doc = as.getDocument(); 129 //add self as listener for sync events from the document's datastore 130 //00 doc.getDataStore().removeDatastoreListener(this); 131 doc.getDataStore().addDatastoreListener(this); 132 } // construction from collection 133 134 135 public String toString() { 136 return super.toString() 137 + "added annots: " + addedAnnotations 138 + "removed annots: " + removedAnnotations 139 + "updated annots: " + updatedAnnotations; 140 } 141 142 143 // /** Two AnnotationSet are equal if their name, the documents of which belong 144 // * to the AnnotationSets and annotations from the sets are the same 145 // */ 146 // public boolean equals(Object other) { 147 // 148 // if (false == other instanceof DatabaseAnnotationSetImpl) { 149 // return super.equals(other); 150 // } 151 // 152 // boolean result = true; 153 // 154 // if (!super.equals((AnnotationSet)other)) { 155 // return false; 156 // } 157 // 158 // DatabaseAnnotationSetImpl target = (DatabaseAnnotationSetImpl)other; 159 // 160 // result = result && this.addedAnnotations.equals(target.addedAnnotations) 161 // && this.removedAnnotations.equals(target.removedAnnotations) 162 // && this.updatedAnnotations.equals(target.updatedAnnotations); 163 // 164 // //FINALLY - CHECK THAT THE SET IS FROM THE SAME DOCUMENT *INSTANCE* 165 // //DO *NOT* USE EQUALS() 166 // result = result && ( this.getDocument() == target.getDocument()); 167 // 168 // return result; 169 // } // equals 170 171 /** 172 * All the events from the document or its annotation sets are handled by 173 * this inner class. 174 */ 175 /* class EventsHandler implements AnnotationListener 176 AnnotationSetListener{ 177 178 179 public void annotationAdded(gate.event.AnnotationSetEvent e) { 180 AnnotationSet set = (AnnotationSet)e.getSource(); 181 String setName = set.getName(); 182 if (setName != DatabaseAnnotationSetImpl.this.name && 183 ! setName.equals(DatabaseAnnotationSetImpl.this.name)) 184 return; 185 Annotation ann = e.getAnnotation(); 186 ann.addAnnotationListener(this); 187 DatabaseAnnotationSetImpl.this.addedAnnotations.add(ann); 188 } 189 190 public void annotationRemoved(AnnotationSetEvent e){ 191 AnnotationSet set = (AnnotationSet)e.getSource(); 192 String setName = set.getName(); 193 if (setName != DatabaseAnnotationSetImpl.this.name && 194 ! setName.equals(DatabaseAnnotationSetImpl.this.name)) 195 return; 196 Annotation ann = e.getAnnotation(); 197 ann.removeAnnotationListener(this); 198 199 //1. check if this annot is in the newly created annotations set 200 if (addedAnnotations.contains(ann)) { 201 //a new annotatyion that was deleted afterwards, remove it from all sets 202 DatabaseAnnotationSetImpl.this.addedAnnotations.remove(ann); 203 return; 204 } 205 //2. check if the annotation was updated, if so, remove it from the 206 //update list 207 if (updatedAnnotations.contains(ann)) { 208 DatabaseAnnotationSetImpl.this.updatedAnnotations.remove(ann); 209 } 210 211 DatabaseAnnotationSetImpl.this.removedAnnotations.add(ann); 212 } 213 214 215 public void annotationUpdated(AnnotationEvent e){ 216 Annotation ann = (Annotation) e.getSource(); 217 218 //check if the annotation is newly created 219 //if so, do not add it to the update list, since it was not stored in the 220 //database yet, so the most recent value will be inserted into the DB upon 221 //DataStore::sync() 222 if (addedAnnotations.contains(ann)) { 223 return; 224 } 225 226 DatabaseAnnotationSetImpl.this.updatedAnnotations.add(ann); 227 } 228 229 }//inner class EventsHandler 230 231 */ 232 233 /** 234 * Called by a datastore when a new resource has been adopted 235 */ 236 public void resourceAdopted(DatastoreEvent evt){ 237 Assert.assertNotNull(evt); 238 Assert.assertNotNull(evt.getResourceID()); 239 240 //check if this is our resource 241 //rememeber - a data store handles many resources 242 if (evt.getResourceID().equals(this.doc.getLRPersistenceId())) { 243 //System.out.println("ASNAME=["+this.getName()+"], resourceAdopted() called"); 244 //we're synced wtith the DB now 245 clearChangeLists(); 246 } 247 } 248 249 /** 250 * Called by a datastore when a resource has been deleted 251 */ 252 public void resourceDeleted(DatastoreEvent evt){ 253 254 Assert.assertNotNull(evt); 255 Assert.assertNotNull(evt.getResourceID()); 256 257 //check if this is our resource 258 //rememeber - a data store handles many resources 259 if (evt.getResourceID().equals(this.doc.getLRPersistenceId())) { 260 //System.out.println("ASNAME=["+this.getName()+"],resourceDeleted() called"); 261 262 //unregister self 263 //this is not the correct way, since the resource is null in this case 264 // DataStore ds = (DataStore)evt.getResource(); 265 DataStore ds = this.doc.getDataStore(); 266 if (ds != null) 267 ds.removeDatastoreListener(this); 268 } 269 270 }//resourceDeleted 271 272 /** 273 * Called by a datastore when a resource has been wrote into the datastore 274 */ 275 public void resourceWritten(DatastoreEvent evt){ 276 Assert.assertNotNull(evt); 277 Assert.assertNotNull(evt.getResourceID()); 278 279 //check if this is our resource 280 //rememeber - a data store handles many resources 281 if (evt.getResourceID().equals(this.doc.getLRPersistenceId())) { 282 //System.out.println("ASNAME=["+this.getName()+"],resourceWritten() called"); 283 284 //clear lists with updates - we're synced with the DB 285 clearChangeLists(); 286 } 287 } 288 289 290 private void clearChangeLists() { 291 292 //ok, we're synced now, clear all lists with changed IDs 293 synchronized(this) { 294 //System.out.println("clearing lists..."); 295 this.addedAnnotations.clear(); 296 this.updatedAnnotations.clear(); 297 this.removedAnnotations.clear(); 298 } 299 } 300 301 public Collection getAddedAnnotations() { 302 //System.out.println("getAddedIDs() called"); 303 HashSet result = new HashSet(); 304 result.addAll(this.addedAnnotations); 305 306 return result; 307 } 308 309 310 public Collection getChangedAnnotations() { 311 //System.out.println("getChangedIDs() called"); 312 HashSet result = new HashSet(); 313 result.addAll(this.updatedAnnotations); 314 315 return result; 316 } 317 318 319 public Collection getRemovedAnnotations() { 320 //System.out.println("getremovedIDs() called..."); 321 HashSet result = new HashSet(); 322 result.addAll(this.removedAnnotations); 323 324 return result; 325 } 326 327 public void annotationUpdated(AnnotationEvent e){ 328 Annotation ann = (Annotation) e.getSource(); 329 330 //check if the annotation is newly created 331 //if so, do not add it to the update list, since it was not stored in the 332 //database yet, so the most recent value will be inserted into the DB upon 333 //DataStore::sync() 334 if (false == this.addedAnnotations.contains(ann)) { 335 this.updatedAnnotations.add(ann); 336 } 337 } 338 339 /** Add an existing annotation. Returns true when the set is modified. */ 340 public boolean add(Object o) throws ClassCastException { 341 342 boolean result = super.add(o); 343 344 if (true == result) { 345 //register as listener for update events from this annotation 346 Annotation ann = (Annotation)o; 347 ann.addAnnotationListener(this); 348 349 //add to the newly created annotations set 350 this.addedAnnotations.add(ann); 351 } 352 353 return result; 354 } 355 356 /** Remove an element from this set. */ 357 public boolean remove(Object o) throws ClassCastException { 358 359 boolean result = super.remove(o); 360 361 if (true == result) { 362 //UNregister as listener for update events from this annotation 363 Annotation ann = (Annotation)o; 364 ann.removeAnnotationListener(this); 365 366 //1. check if this annot is in the newly created annotations set 367 if (this.addedAnnotations.contains(ann)) { 368 //a new annotation that was deleted afterwards, remove it from all sets 369 this.addedAnnotations.remove(ann); 370 } 371 else { 372 373 //2. check if the annotation was updated, if so, remove it from the 374 //update list 375 if (this.updatedAnnotations.contains(ann)) { 376 this.updatedAnnotations.remove(ann); 377 } 378 379 //3. add to the list with deleted anns 380 this.removedAnnotations.add(ann); 381 } 382 } 383 384 return result; 385 } 386 387 388 389 }
|
DatabaseAnnotationSetImpl |
|