1   /*
2    *  TestAnnotation.java
3    *
4    *  Copyright (c) 1998-2005, The University of Sheffield.
5    *
6    *  This file is part of GATE (see http://gate.ac.uk/), and is free
7    *  software, licenced under the GNU Library General Public License,
8    *  Version 2, June 1991 (in the distribution as file licence.html,
9    *  and also available at http://gate.ac.uk/gate/licence.html).
10   *
11   *  Hamish Cunningham, 7/Feb/00
12   *
13   *  $Id: TestAnnotation.java,v 1.47 2005/12/22 21:24:35 kwilliams Exp $
14   */
15  
16  package gate.annotation;
17  
18  import java.util.*;
19  
20  import junit.framework.*;
21  
22  import gate.*;
23  import gate.util.*;
24  
25  /** Tests for the Annotation classes
26    */
27  public class TestAnnotation extends TestCase
28  {
29    /** Debug flag */
30    private static final boolean DEBUG = false;
31  
32    /** Construction */
33    public TestAnnotation(String name) { super(name); }
34  
35    /** A document */
36    protected Document doc1;
37  
38    /** An annotation set */
39    protected AnnotationSet basicAS;
40  
41    /** An empty feature map */
42    protected FeatureMap emptyFeatureMap;
43  
44    /** Fixture set up */
45    public void setUp() throws Exception
46    {
47    Gate.setNetConnected(false);
48      Gate.init();
49      FeatureMap params = Factory.newFeatureMap();
50      params.put(Document.DOCUMENT_URL_PARAMETER_NAME, Gate.getUrl("tests/doc0.html"));
51      params.put(Document.DOCUMENT_MARKUP_AWARE_PARAMETER_NAME, "false");
52      doc1 = (Document)Factory.createResource("gate.corpora.DocumentImpl",
53                                                      params);
54  
55      emptyFeatureMap = new SimpleFeatureMapImpl();
56  
57      basicAS = new AnnotationSetImpl(doc1);
58      FeatureMap fm = new SimpleFeatureMapImpl();
59  
60      basicAS.get("T");          // to trigger type indexing
61      basicAS.get(new Long(0));  // trigger offset index (though add will too)
62  
63      basicAS.add(new Long(10), new Long(20), "T1", fm);    // 0
64      basicAS.add(new Long(10), new Long(20), "T2", fm);    // 1
65      basicAS.add(new Long(10), new Long(20), "T3", fm);    // 2
66      basicAS.add(new Long(10), new Long(20), "T1", fm);    // 3
67  
68      fm = new SimpleFeatureMapImpl();
69      fm.put("pos", "NN");
70      fm.put("author", "hamish");
71      fm.put("version", new Integer(1));
72  
73      basicAS.add(new Long(10), new Long(20), "T1", fm);    // 4
74      basicAS.add(new Long(15), new Long(40), "T1", fm);    // 5
75      basicAS.add(new Long(15), new Long(40), "T3", fm);    // 6
76      basicAS.add(new Long(15), new Long(40), "T1", fm);    // 7
77  
78      fm = new SimpleFeatureMapImpl();
79      fm.put("pos", "JJ");
80      fm.put("author", "the devil himself");
81      fm.put("version", new Long(44));
82      fm.put("created", "monday");
83  
84      basicAS.add(new Long(15), new Long(40), "T3", fm);    // 8
85      basicAS.add(new Long(15), new Long(40), "T1", fm);    // 9
86      basicAS.add(new Long(15), new Long(40), "T1", fm);    // 10
87  
88      // Out.println(basicAS);
89    } // setUp
90  
91  
92    /** Test indexing by offset */
93    public void testOffsetIndex() throws InvalidOffsetException {
94      AnnotationSet as = new AnnotationSetImpl(doc1);
95      AnnotationSet asBuf;
96      Integer newId;
97      FeatureMap fm = new SimpleFeatureMapImpl();
98      Annotation a;
99      Node startNode;
100     Node endNode;
101 
102     newId = as.add(new Long(10), new Long(20), "T", fm);
103     assertEquals(newId.intValue(), 11);
104     a = as.get(newId);
105 
106     startNode = a.getStartNode();
107     endNode = a.getEndNode();
108     assertEquals(startNode.getId().intValue(), 4);
109     assertEquals(endNode.getId().intValue(), 5);
110     assertEquals(startNode.getOffset().longValue(), 10);
111     assertEquals(endNode.getOffset().longValue(), 20);
112 
113     newId = as.add(new Long(10), new Long(30), "T", fm);
114     assertEquals(newId.intValue(), 12);
115     a = as.get(newId);
116 
117     startNode = a.getStartNode();
118     endNode = a.getEndNode();
119     assertEquals(startNode.getId().intValue(), 4);
120     assertEquals(endNode.getId().intValue(), 6);
121     assertEquals(startNode.getOffset().longValue(), 10);
122     assertEquals(endNode.getOffset().longValue(), 30);
123 
124     asBuf = as.get(new Long(10));
125     assertEquals(asBuf.size(), 2);
126 
127   } // testOffsetIndex()
128 
129   /** Test exception throwing */
130   public void testExceptions() {
131     AnnotationSet as = new AnnotationSetImpl(doc1);
132     boolean threwUp = false;
133 
134     try {
135       as.add(new Long(-1), new Long(1), "T", emptyFeatureMap);
136     } catch (InvalidOffsetException e) {
137       threwUp = true;
138     }
139 
140     if(! threwUp) fail("Should have thrown InvalidOffsetException");
141     threwUp = false;
142 
143     try {
144       as.add(new Long(1), new Long(-1), "T", emptyFeatureMap);
145     } catch (InvalidOffsetException e) {
146       threwUp = true;
147     }
148 
149     if(! threwUp) fail("Should have thrown InvalidOffsetException");
150     threwUp = false;
151 
152     try {
153       as.add(new Long(1), new Long(0), "T", emptyFeatureMap);
154     } catch (InvalidOffsetException e) {
155       threwUp = true;
156     }
157 
158     if(! threwUp) fail("Should have thrown InvalidOffsetException");
159     threwUp = false;
160 
161     try {
162       as.add(null, new Long(1), "T", emptyFeatureMap);
163     } catch (InvalidOffsetException e) {
164       threwUp = true;
165     }
166 
167     if(! threwUp) fail("Should have thrown InvalidOffsetException");
168     threwUp = false;
169 
170     try {
171       as.add(new Long(1), null, "T", emptyFeatureMap);
172     } catch (InvalidOffsetException e) {
173       threwUp = true;
174     }
175 
176     if(! threwUp) fail("Should have thrown InvalidOffsetException");
177     threwUp = false;
178 
179     try {
180       as.add(new Long(999999), new Long(100000000), "T", emptyFeatureMap);
181     } catch (InvalidOffsetException e) {
182       threwUp = true;
183     }
184 
185     /*
186     // won't work until the doc size check is implemented
187     if(! threwUp) fail("Should have thrown InvalidOffsetException");
188     */
189     threwUp = false;
190 
191   } // testExceptions()
192 
193   /** Test type index */
194   public void testTypeIndex() throws Exception {
195     FeatureMap params = Factory.newFeatureMap();
196     params.put(Document.DOCUMENT_URL_PARAMETER_NAME, Gate.getUrl("tests/doc0.html"));
197     params.put(Document.DOCUMENT_MARKUP_AWARE_PARAMETER_NAME, "false");
198     Document doc = (Document)Factory.createResource("gate.corpora.DocumentImpl",
199                                                     params);
200     AnnotationSet as = new AnnotationSetImpl(doc);
201     AnnotationSet asBuf;
202     FeatureMap fm = new SimpleFeatureMapImpl();
203     Annotation a;
204     Node startNode;
205     Node endNode;
206 
207     // to trigger type indexing
208     as.get("T");
209     as.add(new Long(10), new Long(20), "T1", fm);    // 0
210     as.add(new Long(10), new Long(20), "T2", fm);    // 1
211     as.add(new Long(10), new Long(20), "T3", fm);    // 2
212     as.add(new Long(10), new Long(20), "T1", fm);    // 3
213     as.add(new Long(10), new Long(20), "T1", fm);    // 4
214     as.add(new Long(10), new Long(20), "T1", fm);    // 5
215     as.add(new Long(10), new Long(20), "T3", fm);    // 6
216     as.add(new Long(10), new Long(20), "T1", fm);    // 7
217     as.add(new Long(10), new Long(20), "T3", fm);    // 8
218     as.add(new Long(10), new Long(20), "T1", fm);    // 9
219     as.add(new Long(10), new Long(20), "T1", fm);    // 10
220 
221     asBuf = as.get("T");
222     assertEquals(null, asBuf);
223 
224     asBuf = as.get("T1");
225     assertEquals(7, asBuf.size());
226     asBuf = as.get("T2");
227     assertEquals(1, asBuf.size());
228     asBuf = as.get("T3");
229     assertEquals(3, asBuf.size());
230 
231     // let's check that we've only got two nodes, what the ids are and so on;
232     // first construct a sorted set of annotations
233     SortedSet sortedAnnots = new TreeSet(as);
234 
235     // for checking the annotation id
236     int idCounter = 0;
237     Iterator iter = sortedAnnots.iterator();
238     while(iter.hasNext()) {
239       a = (Annotation) iter.next();
240 
241       // check annot ids
242       assertEquals(idCounter++, a.getId().intValue());
243 
244       startNode = a.getStartNode();
245       endNode = a.getEndNode();
246 
247       // start node id
248       assertEquals(0,  startNode.getId().intValue());
249 
250       // start offset
251       assertEquals(10, startNode.getOffset().longValue());
252 
253       // end id
254       assertEquals(1,  endNode.getId().intValue());
255 
256       // end offset
257       assertEquals(20, endNode.getOffset().longValue());
258     }
259 
260   } // testTypeIndex()
261 
262   /** Test the annotations set add method that uses existing nodes */
263   public void testAddWithNodes() throws Exception {
264     FeatureMap params = Factory.newFeatureMap();
265     params.put(Document.DOCUMENT_URL_PARAMETER_NAME, Gate.getUrl("tests/doc0.html"));
266     params.put(Document.DOCUMENT_MARKUP_AWARE_PARAMETER_NAME, "false");
267     Document doc = (Document)Factory.createResource("gate.corpora.DocumentImpl",
268                                                     params);
269     AnnotationSet as = new AnnotationSetImpl(doc);
270     AnnotationSet asBuf;
271     Integer newId;
272     FeatureMap fm = new SimpleFeatureMapImpl();
273     Annotation a;
274     Node startNode;
275     Node endNode;
276 
277     // to trigger type indexing
278     as.get("T");
279     newId = as.add(new Long(10), new Long(20), "T1", fm);    // 0
280     a = as.get(newId);
281     startNode = a.getStartNode();
282     endNode = a.getEndNode();
283 
284     as.add(startNode, endNode, "T2", fm);    // 1
285     as.add(startNode, endNode, "T3", fm);    // 2
286     as.add(startNode, endNode, "T1", fm);    // 3
287     as.add(startNode, endNode, "T1", fm);    // 4
288     as.add(startNode, endNode, "T1", fm);    // 5
289     as.add(startNode, endNode, "T3", fm);    // 6
290     as.add(startNode, endNode, "T1", fm);    // 7
291     as.add(startNode, endNode, "T3", fm);    // 8
292     as.add(startNode, endNode, "T1", fm);    // 9
293     as.add(startNode, endNode, "T1", fm);    // 10
294 
295     asBuf = as.get("T");
296     assertEquals(null, asBuf);
297 
298     asBuf = as.get("T1");
299     assertEquals(7, asBuf.size());
300     asBuf = as.get("T2");
301     assertEquals(1, asBuf.size());
302     asBuf = as.get("T3");
303     assertEquals(3, asBuf.size());
304 
305     // let's check that we've only got two nodes, what the ids are and so on;
306     // first construct a sorted set of annotations
307     SortedSet sortedAnnots = new TreeSet(as);
308 
309     // for checking the annotation id
310     int idCounter = 0;
311     Iterator iter = sortedAnnots.iterator();
312     while(iter.hasNext()) {
313       a = (Annotation) iter.next();
314       // check annot ids
315       assertEquals(idCounter++, a.getId().intValue());
316 
317       startNode = a.getStartNode();
318       endNode = a.getEndNode();
319 
320       // start node id
321       assertEquals(0,  startNode.getId().intValue());
322 
323       // start offset
324       assertEquals(10, startNode.getOffset().longValue());
325 
326       // end id
327       assertEquals(1,  endNode.getId().intValue());
328 
329       // end offset
330       assertEquals(20, endNode.getOffset().longValue());
331     }
332 
333   } // testAddWithNodes()
334 
335   /** Test complex get (with type, offset and feature contraints) */
336   public void testComplexGet() throws InvalidOffsetException {
337     AnnotationSet asBuf;
338 
339     FeatureMap constraints = new SimpleFeatureMapImpl();
340     constraints.put("pos", "NN");
341 
342     //Out.println(basicAS);
343     //Out.println(constraints);
344 
345     asBuf = basicAS.get("T1", constraints);
346     assertEquals(3, asBuf.size());
347     asBuf = basicAS.get("T3", constraints);
348     assertEquals(1, asBuf.size());
349     asBuf = basicAS.get("T1", constraints, new Long(12));
350     assertEquals(2, asBuf.size());
351     asBuf = basicAS.get("T1", constraints, new Long(10));
352     assertEquals(1, asBuf.size());
353     asBuf = basicAS.get("T1", constraints, new Long(11));
354     assertEquals(2, asBuf.size());
355     asBuf = basicAS.get("T1", constraints, new Long(9));
356     assertEquals(1, asBuf.size());
357 
358     constraints.put("pos", "JJ");
359     //Out.println(constraints);
360     asBuf = basicAS.get("T1", constraints, new Long(0));
361     assertEquals(null, asBuf);
362     asBuf = basicAS.get("T1", constraints, new Long(14));
363     assertEquals(2, asBuf.size());
364 
365     constraints.put("author", "valentin");
366     asBuf = basicAS.get("T1", constraints, new Long(14));
367     assertEquals(null, asBuf);
368 
369     constraints.put("author", "the devil himself");
370     asBuf = basicAS.get("T1", constraints, new Long(14));
371     assertEquals(2, asBuf.size());
372 
373     asBuf = basicAS.get("T1", constraints, new Long(5));
374     assertEquals(null, asBuf);
375 
376     constraints.put("this feature isn't", "there at all");
377     asBuf = basicAS.get("T1", constraints, new Long(14));
378     assertEquals(null, asBuf);
379 
380   } // testComplexGet()
381 
382   /** Test remove */
383   public void testRemove() {
384     AnnotationSet asBuf = basicAS.get("T1");
385     assertEquals(7, asBuf.size());
386     asBuf = basicAS.get(new Long(9));
387     assertEquals(5, asBuf.size());
388 
389     basicAS.remove(basicAS.get(new Integer(0)));
390 
391     assertEquals(10, basicAS.size());
392     assertEquals(10, ((AnnotationSetImpl) basicAS).annotsById.size());
393 
394     asBuf = basicAS.get("T1");
395     assertEquals(6, asBuf.size());
396 
397     asBuf = basicAS.get(new Long(9));
398     assertEquals(4, asBuf.size());
399     assertEquals(null, basicAS.get(new Integer(0)));
400     basicAS.remove(basicAS.get(new Integer(8)));
401     assertEquals(9, basicAS.size());
402     basicAS.removeAll(basicAS);
403     assertEquals(null, basicAS.get());
404     assertEquals(null, basicAS.get("T1"));
405     assertEquals(null, basicAS.get(new Integer(0)));
406   } // testRemove()
407 
408   public void testRemoveInexistant() throws Exception{
409     basicAS.add(new Long(0), new Long(10), "Foo", emptyFeatureMap);
410     Annotation ann = (Annotation)basicAS.get("Foo").iterator().next();
411     basicAS.remove(ann);
412     //the second remove should do nothing...
413     basicAS.remove(ann);
414   }
415 
416   /** Test iterator remove */
417   public void testIteratorRemove() {
418     AnnotationSet asBuf = basicAS.get("T1");
419     assertEquals(7, asBuf.size());
420     asBuf = basicAS.get(new Long(9));
421     assertEquals(5, asBuf.size());
422 
423     // remove annotation with id 0; this is returned last by the
424     // iterator
425     Iterator iter = basicAS.iterator();
426     while(iter.hasNext())
427       iter.next();
428     iter.remove();
429 
430     assertEquals(10, basicAS.size());
431     assertEquals(10, ((AnnotationSetImpl) basicAS).annotsById.size());
432     asBuf = basicAS.get("T1");
433     assertEquals(6, asBuf.size());
434     asBuf = basicAS.get(new Long(9));
435     assertEquals(4, asBuf.size());
436     assertEquals(null, basicAS.get(new Integer(0)));
437     basicAS.remove(basicAS.get(new Integer(8)));
438 
439   } // testIteratorRemove()
440 
441   /** Test iterator */
442   public void testIterator() {
443     Iterator iter = basicAS.iterator();
444     Annotation[] annots = new Annotation[basicAS.size()];
445     int i = 0;
446 
447     while(iter.hasNext()) {
448       Annotation a = (Annotation) iter.next();
449       annots[i++] = a;
450 
451       assertTrue(basicAS.contains(a));
452       iter.remove();
453       assertTrue(!basicAS.contains(a));
454     } // while
455 
456     i = 0;
457     while(i < annots.length) {
458       basicAS.add(annots[i++]);
459       assertEquals(i, basicAS.size());
460     } // while
461 
462     AnnotationSet asBuf = basicAS.get("T1");
463     assertEquals(7, asBuf.size());
464     asBuf = basicAS.get(new Long(9));
465     assertEquals(5, asBuf.size());
466   } // testIterator
467 
468   /** Test Set methods */
469   public void testSetMethods() {
470     Annotation a = basicAS.get(new Integer(6));
471     assertTrue(basicAS.contains(a));
472 
473     Annotation[] annotArray =
474       (Annotation[]) basicAS.toArray(new Annotation[0]);
475     Object[] annotObjectArray = basicAS.toArray();
476     assertEquals(11, annotArray.length);
477     assertEquals(11, annotObjectArray.length);
478 
479     SortedSet sortedAnnots = new TreeSet(basicAS);
480     annotArray = (Annotation[]) sortedAnnots.toArray(new Annotation[0]);
481     for(int i = 0; i<11; i++)
482       assertTrue( annotArray[i].getId().equals(new Integer(i)) );
483 
484     Annotation a1 = basicAS.get(new Integer(3));
485     Annotation a2 = basicAS.get(new Integer(4));
486     Set a1a2 = new HashSet();
487     a1a2.add(a1);
488     a1a2.add(a2);
489     assertTrue(basicAS.contains(a1));
490     assertTrue(basicAS.containsAll(a1a2));
491     basicAS.removeAll(a1a2);
492 
493     assertEquals(9, basicAS.size());
494     assertTrue(! basicAS.contains(a1));
495     assertTrue(! basicAS.containsAll(a1a2));
496 
497     //this will not work anymore as the semantics of addAll has changed (new
498     //annotations are created in order to avoid ID clashes
499 /*
500     basicAS.addAll(a1a2);
501     assertTrue(basicAS.contains(a2));
502     assertTrue(basicAS.containsAll(a1a2));
503 
504     assertTrue(basicAS.retainAll(a1a2));
505     assertTrue(basicAS.equals(a1a2));
506 */
507     basicAS.clear();
508     assertTrue(basicAS.isEmpty());
509 
510   } // testSetMethods()
511 
512   /** Test AnnotationSetImpl */
513   public void testAnnotationSet() throws Exception {
514     // constuct an empty AS
515     FeatureMap params = Factory.newFeatureMap();
516     params.put(Document.DOCUMENT_URL_PARAMETER_NAME, Gate.getUrl("tests/doc0.html"));
517     params.put(Document.DOCUMENT_MARKUP_AWARE_PARAMETER_NAME, "false");
518     Document doc = (Document)Factory.createResource("gate.corpora.DocumentImpl",
519                                                     params);
520 
521     AnnotationSet as = new AnnotationSetImpl(doc);
522     assertEquals(as.size(), 0);
523 
524     // add some annotations
525     FeatureMap fm1 = Factory.newFeatureMap();
526     fm1.put("test", "my-value");
527     FeatureMap fm2 = Factory.newFeatureMap();
528     fm2.put("test", "my-value-different");
529     FeatureMap fm3 = Factory.newFeatureMap();
530     fm3.put("another test", "different my-value");
531 
532     Integer newId;
533     newId =
534       as.add(new Long(0), new Long(10), "Token", fm1);
535     assertEquals(newId.intValue(), 0);
536     newId =
537       as.add(new Long(11), new Long(12), "Token", fm2);
538     assertEquals(newId.intValue(), 1);
539     assertEquals(as.size(), 2);
540     assertTrue(! as.isEmpty());
541     newId =
542       as.add(new Long(15), new Long(22), "Syntax", fm1);
543 
544     // get by ID; remove; add(object)
545     Annotation a = as.get(new Integer(1));
546     as.remove(a);
547     assertEquals(as.size(), 2);
548     as.add(a);
549     assertEquals(as.size(), 3);
550 
551     // iterate over the annotations
552     Iterator iter = as.iterator();
553     while(iter.hasNext()) {
554       a = (Annotation) iter.next();
555       if(a.getId().intValue() != 2)
556         assertEquals(a.getType(), "Token");
557       assertEquals(a.getFeatures().size(), 1);
558     }
559 
560     // add some more
561     newId =
562       as.add(new Long(0), new Long(12), "Syntax", fm3);
563     assertEquals(newId.intValue(), 3);
564     newId =
565       as.add(new Long(14), new Long(22), "Syntax", fm1);
566     assertEquals(newId.intValue(), 4);
567     assertEquals(as.size(), 5);
568     newId =
569       as.add(new Long(15), new Long(22), "Syntax", new SimpleFeatureMapImpl());
570 
571     //get by feature names
572     HashSet hs = new HashSet();
573     hs.add("test");
574     AnnotationSet fnSet = as.get("Token", hs);
575     assertEquals(fnSet.size(), 2);
576     //now try without a concrete type, just features
577     //we'll get some Syntax ones now too
578     fnSet = as.get(null, hs);
579     assertEquals(fnSet.size(), 4);
580 
581 
582     // indexing by type
583     ((AnnotationSetImpl) as).indexByType();
584     AnnotationSet tokenAnnots = as.get("Token");
585     assertEquals(tokenAnnots.size(), 2);
586 
587     // indexing by position
588     AnnotationSet annotsAfter10 = as.get(new Long(15));
589     if(annotsAfter10 == null)
590       fail("no annots found after offset 10");
591     assertEquals(annotsAfter10.size(), 2);
592 
593   } // testAnnotationSet
594   /** Test suite routine for the test runner */
595   public static Test suite() {
596     return new TestSuite(TestAnnotation.class);
597   } // suite
598 
599   /** Test get with offset and no annotation starting at given offset */
600   public void _testGap() throws InvalidOffsetException {
601     AnnotationSet as = basicAS;
602     as.clear();
603     FeatureMap fm = Factory.newFeatureMap();
604     fm.put("A", "B");
605     as.add(new Long(0), new Long(10), "foo", fm);
606     as.add(new Long(11), new Long(20), "foo", fm);
607     as.add(new Long(10), new Long(11), "space", fm);
608 
609     //do the input selection (ignore spaces)
610     Set input = new HashSet();
611     input.add("foo");
612     input.add("foofoo");
613     AnnotationSet annotations = null;
614 
615     if(input.isEmpty()) annotations = as;
616     else{
617       Iterator typesIter = input.iterator();
618       AnnotationSet ofOneType = null;
619 
620       while(typesIter.hasNext()){
621         ofOneType = as.get((String)typesIter.next());
622 
623         if(ofOneType != null){
624           //System.out.println("Adding " + ofOneType.getAllTypes());
625           if(annotations == null) annotations = ofOneType;
626           else annotations.addAll(ofOneType);
627         }
628       }
629     }
630     /* if(annotations == null) annotations = new AnnotationSetImpl(doc); */
631     if (DEBUG)
632       Out.println(
633         "Actual input:" + annotations.getAllTypes() + "\n" + annotations
634       );
635 
636     AnnotationSet res =
637       annotations.get("foo", Factory.newFeatureMap(), new Long(10));
638 
639     if (DEBUG)
640       Out.println(res);
641     assertTrue(!res.isEmpty());
642   }
643 
644   /** Test Overlaps */
645   public void testOverlapsAndCoextensive() throws InvalidOffsetException {
646     Node node1 = new NodeImpl(new Integer(1),new Long(10));
647     Node node2 = new NodeImpl(new Integer(2),new Long(20));
648     Node node4 = new NodeImpl(new Integer(4),new Long(15));
649     Node node5 = new NodeImpl(new Integer(5),new Long(20));
650     Node node6 = new NodeImpl(new Integer(6),new Long(30));
651 
652     FeatureMap fm1 = new SimpleFeatureMapImpl();
653     fm1.put("color","red");
654     fm1.put("Age",new Long(25));
655     fm1.put(new Long(23), "Cristian");
656 
657     FeatureMap fm2 = new SimpleFeatureMapImpl();
658     fm2.put("color","red");
659     fm2.put("Age",new Long(25));
660     fm2.put(new Long(23), "Cristian");
661 
662     FeatureMap fm4 = new SimpleFeatureMapImpl();
663     fm4.put("color","red");
664     fm4.put("Age",new Long(26));
665     fm4.put(new Long(23), "Cristian");
666 
667     FeatureMap fm3 = new SimpleFeatureMapImpl();
668     fm3.put("color","red");
669     fm3.put("Age",new Long(25));
670     fm3.put(new Long(23), "Cristian");
671     fm3.put("best",new Boolean(true));
672 
673     // Start=10, End = 20
674     Annotation annot1 = createAnnotation(new Integer(1),
675                                            node1,
676                                            node2,
677                                            "pos",
678                                            null);
679     // Start=20, End = 30
680     Annotation annot2 = createAnnotation (new Integer(2),
681                                             node2,
682                                             node6,
683                                             "pos",
684                                             null);
685     // Start=20, End = 30
686     Annotation annot3 = createAnnotation (new Integer(3),
687                                             node5,
688                                             node6,
689                                             "pos",
690                                             null);
691     // Start=20, End = 20
692     Annotation annot4 = createAnnotation (new Integer(4),
693                                             node2,
694                                             node5,
695                                             "pos",
696                                             null);
697     // Start=10, End = 30
698     Annotation annot5 = createAnnotation (new Integer(5),
699                                             node1,
700                                             node6,
701                                             "pos",
702                                             null);
703     // Start=10, End = 15
704     Annotation annot6 = createAnnotation (new Integer(6),
705                                             node1,
706                                             node4,
707                                             "pos",
708                                             null);
709     // Start=null, End = null
710     Annotation annot7 = createAnnotation (new Integer(7),
711                                             null,
712                                             null,
713                                             "pos",
714                                             null);
715 
716     // MAP
717     // annot1 -> Start=10, End = 20
718     // annot2 -> Start=20, End = 30
719     // annot3 -> Start=20, End = 30
720     // annot4 -> Start=20, End = 20
721     // annot5 -> Start=10, End = 30
722     // annot6 -> Start=10, End = 15
723 
724     // Not overlaping situations
725    assertTrue("Those annotations does not overlap!",!annot1.overlaps(annot3));
726    assertTrue("Those annotations does not overlap!",!annot1.overlaps(annot2));
727    assertTrue("Those annotations does not overlap!",!annot2.overlaps(annot1));
728    assertTrue("Those annotations does not overlap!",!annot3.overlaps(annot1));
729    assertTrue("Those annotations does not overlap!",!annot4.overlaps(annot6));
730    assertTrue("Those annotations does not overlap!",!annot6.overlaps(annot4));
731 
732    assertTrue("Those annotations does not overlap!",!annot6.overlaps(null));
733    assertTrue("Those annotations does not overlap!",!annot1.overlaps(annot7));
734 
735    // Overlaping situations
736    assertTrue("Those annotations does overlap!",annot4.overlaps(annot5));
737    assertTrue("Those annotations does overlap!",annot5.overlaps(annot4));
738    assertTrue("Those annotations does overlap!",annot1.overlaps(annot6));
739    assertTrue("Those annotations does overlap!",annot6.overlaps(annot1));
740    assertTrue("Those annotations does overlap!",annot2.overlaps(annot5));
741    assertTrue("Those annotations does overlap!",annot5.overlaps(annot2));
742 
743    // Not coextensive situations
744    assertTrue("Those annotations are not coextensive!",!annot1.coextensive(annot2));
745    assertTrue("Those annotations are not coextensive!",!annot2.coextensive(annot1));
746    assertTrue("Those annotations are not coextensive!",!annot4.coextensive(annot3));
747    assertTrue("Those annotations are not coextensive!",!annot3.coextensive(annot4));
748    assertTrue("Those annotations are not coextensive!",!annot4.coextensive(annot7));
749    assertTrue("Those annotations are not coextensive!",!annot5.coextensive(annot6));
750    assertTrue("Those annotations are not coextensive!",!annot6.coextensive(annot5));
751    //Coextensive situations
752    assertTrue("Those annotations are coextensive!",annot2.coextensive(annot2));
753    assertTrue("Those annotations are coextensive!",annot2.coextensive(annot3));
754    assertTrue("Those annotations are coextensive!",annot3.coextensive(annot2));
755 
756   }//testOverlapsAndCoextensive
757 
758   /** Test Coextensive */
759   public void testIsPartiallyCompatibleAndCompatible()
760                                                 throws InvalidOffsetException {
761     Node node1 = new NodeImpl(new Integer(1),new Long(10));
762     Node node2 = new NodeImpl(new Integer(2),new Long(20));
763     Node node4 = new NodeImpl(new Integer(4),new Long(15));
764     Node node5 = new NodeImpl(new Integer(5),new Long(20));
765     Node node6 = new NodeImpl(new Integer(6),new Long(30));
766 
767     FeatureMap fm1 = new SimpleFeatureMapImpl();
768     fm1.put("color","red");
769     fm1.put("Age",new Long(25));
770     fm1.put(new Long(23), "Cristian");
771 
772     FeatureMap fm2 = new SimpleFeatureMapImpl();
773     fm2.put("color","red");
774     fm2.put("Age",new Long(25));
775     fm2.put(new Long(23), "Cristian");
776 
777     FeatureMap fm4 = new SimpleFeatureMapImpl();
778     fm4.put("color","red");
779     fm4.put("Age",new Long(26));
780     fm4.put(new Long(23), "Cristian");
781 
782     FeatureMap fm3 = new SimpleFeatureMapImpl();
783     fm3.put("color","red");
784     fm3.put("Age",new Long(25));
785     fm3.put(new Long(23), "Cristian");
786     fm3.put("best",new Boolean(true));
787 
788     // Start=10, End = 20
789     Annotation annot1 = createAnnotation(new Integer(1),
790                                            node1,
791                                            node2,
792                                            "pos",
793                                            fm1);
794     // Start=20, End = 30
795     Annotation annot2 = createAnnotation (new Integer(2),
796                                             node2,
797                                             node6,
798                                             "pos",
799                                             fm2);
800     // Start=20, End = 30
801     Annotation annot3 = createAnnotation (new Integer(3),
802                                             node5,
803                                             node6,
804                                             "pos",
805                                             fm3);
806     // Start=20, End = 20
807     Annotation annot4 = createAnnotation (new Integer(4),
808                                             node2,
809                                             node5,
810                                             "pos",
811                                             fm4);
812     // Start=10, End = 30
813     Annotation annot5 = createAnnotation (new Integer(5),
814                                             node1,
815                                             node6,
816                                             "pos",
817                                             fm3);
818     // Start=10, End = 15
819     Annotation annot6 = createAnnotation (new Integer(6),
820                                             node1,
821                                             node4,
822                                             "pos",
823                                             fm1);
824 
825 // MAP
826   /*
827    annot1 -> Start=10, End = 20,{color="red",Age="25",23="Cristian"}
828    annot2 -> Start=20, End = 30,{color="red",Age="25",23="Cristian"}
829    annot3 -> Start=20, End = 30,{color="red",Age="25",23="Cristian",best="true"}
830    annot4 -> Start=20, End = 20,{color="red",Age="26",23="Cristian"}
831    annot5 -> Start=10, End = 30,{color="red",Age="25",23="Cristian",best="true"}
832    annot6 -> Start=10, End = 15,{color="red",Age="25",23="Cristian"}
833   */
834   // Not compatible situations
835   assertTrue("Those annotations are not compatible!",!annot3.isCompatible(annot2));
836 
837   // Not partially compatible situations
838   // They don't overlap
839   assertTrue("Those annotations("+ annot1 +" & " +
840                                annot2+ ") are not partially compatible!",
841                                        !annot1.isPartiallyCompatible(annot2));
842 
843   // Again they don't overlap
844   assertTrue("Those annotations("+ annot1 +" & " +
845                                annot3+ ") are not partially compatible!",
846                                        !annot1.isPartiallyCompatible(annot3));
847   // Fails because of the age value
848   assertTrue("Those annotations("+ annot1 +" & " +
849                                annot4+ ") are not partially compatible!",
850                                        !annot1.isPartiallyCompatible(annot4));
851   // Fails because of the value of Age
852   assertTrue("Those annotations("+ annot4 +" & " +
853                                annot5+ ") are not partially compatible!",
854                                        !annot4.isPartiallyCompatible(annot5));
855   // Features from annot6 does not subsumes features annot3
856   assertTrue("Those annotations("+ annot3 +" & " +
857                                annot6+ ") are not partially compatible!",
858                                !annot3.isPartiallyCompatible(annot6,null));
859   // Features from annot2 does not subsumes features annot5
860   assertTrue("Those annotations("+ annot5 +" & " +
861                                annot2+ ") are not partially compatible!",
862                                !annot5.isPartiallyCompatible(annot2,null));
863   Set keySet = new HashSet();
864   // They don't overlap
865   assertTrue("Those annotations("+ annot2 +" & " +
866                                annot4+ ") are not partially compatible!",
867                                !annot2.isPartiallyCompatible(annot4,keySet));
868   keySet.add("color");
869   keySet.add("Age");
870   keySet.add("best");
871   // Fails because of best feture
872   assertTrue("Those annotations("+ annot5 +" & " +
873                                annot2+ ") are not partially compatible!",
874                                !annot5.isPartiallyCompatible(annot2,keySet));
875   // Fails because start=end in both cases and they don't overlap
876   assertTrue("Those annotations("+ annot4 +" & " +
877                                annot4+ ") are not partially compatible!",
878                                         !annot4.isPartiallyCompatible(annot4));
879 
880   /*
881    annot1 -> Start=10, End = 20,{color="red",Age="25",23="Cristian"}
882    annot2 -> Start=20, End = 30,{color="red",Age="25",23="Cristian"}
883    annot3 -> Start=20, End = 30,{color="red",Age="25",23="Cristian",best="true"}
884    annot4 -> Start=20, End = 20,{color="red",Age="26",23="Cristian"}
885    annot5 -> Start=10, End = 30,{color="red",Age="25",23="Cristian",best="true"}
886    annot6 -> Start=10, End = 15,{color="red",Age="25",23="Cristian"}
887   */
888 
889   // Compatible situations
890   assertTrue("Those annotations("+ annot2 +" & " +
891                                annot3+ ") should be compatible!",
892                                       annot2.isCompatible(annot3));
893   assertTrue("Those annotations("+ annot2 +" & " +
894                                annot3+ ") should be compatible!",
895                                       annot2.isCompatible(annot3,null));
896   assertTrue("Those annotations("+ annot2 +" & " +
897                                annot3+ ") should be compatible!",
898                                      annot2.isCompatible(annot3,new HashSet()));
899   assertTrue("Those annotations("+ annot4 +" & " +
900                                annot4+ ") should be compatible!",
901                                         annot4.isCompatible(annot4));
902   keySet = new HashSet();
903   keySet.add("color");
904   keySet.add(new Long(23));
905   assertTrue("Those annotations("+ annot3 +" & " +
906                                annot2+ ") should be compatible!",
907                                       annot3.isCompatible(annot2,keySet));
908 
909   // Partially compatible situations
910   assertTrue("Those annotations("+ annot2 +" & " +
911                                annot3+ ") should be partially compatible!",
912                                         annot2.isPartiallyCompatible(annot3));
913   assertTrue("Those annotations("+ annot2 +" & " +
914                                annot2+ ") should be partially compatible!",
915                                         annot2.isPartiallyCompatible(annot2));
916   assertTrue("Those annotations are partially compatible!",
917                                         annot1.isPartiallyCompatible(annot5));
918   assertTrue("Those annotations are partially compatible!",
919                                         annot1.isPartiallyCompatible(annot6));
920   assertTrue("Those annotations are partially compatible!",
921                                         annot3.isPartiallyCompatible(annot5));
922   assertTrue("Those annotations are partially compatible!",
923                                         annot5.isPartiallyCompatible(annot3));
924   assertTrue("Those annotations are partially compatible!",
925                                         annot6.isPartiallyCompatible(annot5));
926 
927   }// testIsPartiallyCompatibleAndCompatible
928 
929 
930   public void testFeatureSubsumeMethods(){
931 
932     FeatureMap fm1 = Factory.newFeatureMap();
933     fm1.put("k1","v1");
934     fm1.put("k2","v2");
935 
936     FeatureMap fm2 = Factory.newFeatureMap();
937     fm2.put("k1","v1");
938 
939     Set featKeysSet1 = new HashSet();
940     featKeysSet1.add("k1");
941     featKeysSet1.add("k2");
942     featKeysSet1.add("k3");
943     featKeysSet1.add("k4");
944 
945     assertTrue(fm1 + " should subsume " + fm2 + " using the key set" +
946                                featKeysSet1,fm1.subsumes(fm2, featKeysSet1));
947     assertTrue(fm1 + " should subsume " + fm2 +
948                             " taking all feat into consideration",
949                             fm1.subsumes(fm2, null));
950 
951     FeatureMap fm3 = Factory.newFeatureMap();
952     fm3.put("k1","v1");
953     fm3.put("k2","v2");
954     fm3.put("k3",new Integer(3));
955 
956     Set featKeysSet2 = new HashSet();
957     featKeysSet2.add("k1");
958 
959     assertTrue(fm1 + " should subsume " + fm3 + " using the key set" +
960                           featKeysSet2,fm1.subsumes(fm3, featKeysSet2));
961     assertTrue(fm1 + " should NOT subsume " + fm3 +
962                                 " taking all feats into consideration",
963                                 !fm1.subsumes(fm3,null));
964 
965     FeatureMap fm4 = Factory.newFeatureMap();
966     fm4.put("k1",new Integer(2));
967     fm4.put("k2","v2");
968     fm4.put("k3","v3");
969 
970     Set featKeysSet3 = new HashSet();
971     featKeysSet3.add("k2");
972 
973     assertTrue(fm3 + " should subsume " + fm4 + " using the key set" +
974                               featKeysSet3, fm4.subsumes(fm3,featKeysSet3));
975     assertTrue(fm4 + " should NOT subsume " + fm3 +
976                                 " taking all feats into consideration",
977                                 !fm4.subsumes(fm3,null));
978 
979 
980   }// testFeatureSubsumeMethods();
981 
982   protected Annotation createAnnotation
983     (Integer id, Node start, Node end, String type, FeatureMap features) {
984       return new AnnotationImpl(id, start, end, type, features);
985   }
986   
987   public static void main(String[] args){
988 
989     try{
990       TestAnnotation testAnnot = new TestAnnotation("");
991       testAnnot.setUp();
992       testAnnot.testIterator();
993       testAnnot._testGap();
994       testAnnot.tearDown();
995       testAnnot.testOverlapsAndCoextensive();
996       testAnnot.testIsPartiallyCompatibleAndCompatible();
997     }catch(Throwable t){
998       t.printStackTrace();
999     }
1000  }
1001} // class TestAnnotation
1002
1003