|
GateFormatXmlDocumentHandler |
|
1 /* 2 * GateFormatXmlDocumentHandler.java 3 * 4 * Copyright (c) 1998-2001, 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 * Cristian URSU, 22 Nov 2000 12 * 13 * $Id: GateFormatXmlDocumentHandler.java,v 1.21 2002/07/05 12:04:35 nasso Exp $ 14 */ 15 16 package gate.xml; 17 18 import java.util.*; 19 import java.lang.reflect.*; 20 21 import gate.corpora.*; 22 import gate.annotation.*; 23 import gate.util.*; 24 import gate.*; 25 import gate.event.*; 26 27 28 import org.xml.sax.*; 29 import org.xml.sax.helpers.*; 30 31 32 /** 33 * Implements the behaviour of the XML reader. This is the reader for 34 * Gate Xml documents saved with DocumentImplementation.toXml() method. 35 */ 36 public class GateFormatXmlDocumentHandler extends DefaultHandler{ 37 /** Debug flag */ 38 private static final boolean DEBUG = false; 39 40 /** 41 */ 42 public GateFormatXmlDocumentHandler(gate.Document aDocument){ 43 // This string contains the plain text (the text without markup) 44 tmpDocContent = new StringBuffer(aDocument.getContent().size().intValue()); 45 46 // Colector is used later to transform all custom objects into annotation 47 // objects 48 colector = new LinkedList(); 49 50 // The Gate document 51 doc = aDocument; 52 currentAnnotationSet = doc.getAnnotations(); 53 }//GateFormatXmlDocumentHandler 54 55 /** 56 * This method is called when the SAX parser encounts the beginning of the 57 * XML document. 58 */ 59 public void startDocument() throws org.xml.sax.SAXException { 60 }// startDocument 61 62 /** 63 * This method is called when the SAX parser encounts the end of the 64 * XML document. 65 * Here we set the content of the gate Document to be the one generated 66 * inside this class (tmpDocContent). 67 * After that we use the colector to generate all the annotation reffering 68 * this new gate document. 69 */ 70 public void endDocument() throws org.xml.sax.SAXException { 71 72 // replace the document content with the one without markups 73 doc.setContent(new DocumentContentImpl(tmpDocContent.toString())); 74 long docSize = doc.getContent().size().longValue(); 75 76 // fire the status listener 77 fireStatusChangedEvent("Total elements: " + elements); 78 79 }// endDocument 80 81 /** 82 * This method is called when the SAX parser encounts the beginning of an 83 * XML element. 84 */ 85 public void startElement (String uri, String qName, String elemName, 86 Attributes atts){ 87 88 // Inform the progress listener to fire only if no of elements processed 89 // so far is a multiple of ELEMENTS_RATE 90 if ((++elements % ELEMENTS_RATE) == 0 ) 91 fireStatusChangedEvent("Processed elements : " + elements); 92 93 // Set the curent element being processed 94 currentElementStack.add(elemName); 95 96 if("AnnotationSet".equals(elemName)) 97 processAnnotationSetElement(atts); 98 99 if("Annotation".equals(elemName)) 100 processAnnotationElement(atts); 101 102 if("Feature".equals(elemName)) 103 processFeatureElement(atts); 104 105 if("Name".equals(elemName)) 106 processNameElement(atts); 107 108 if("Value".equals(elemName)) 109 processValueElement(atts); 110 111 if("Node".equals(elemName)) 112 processNodeElement(atts); 113 }// startElement 114 115 /** 116 * This method is called when the SAX parser encounts the end of an 117 * XML element. 118 */ 119 public void endElement (String uri, String qName, String elemName ) 120 throws SAXException{ 121 122 currentElementStack.pop(); 123 // Deal with Annotation 124 if ("Annotation".equals(elemName)){ 125 if (currentFeatureMap == null) 126 currentFeatureMap = Factory.newFeatureMap(); 127 currentAnnot.setFM(currentFeatureMap); 128 colector.add(currentAnnot); 129 // Reset current Annot and current featue map 130 currentAnnot = null; 131 currentFeatureMap = null; 132 return; 133 }// End if 134 // Deal with Value 135 if ("Value".equals(elemName) && "Feature".equals( 136 (String)currentElementStack.peek())){ 137 // If the Value tag was empty, then an empty string will be created. 138 if (currentFeatureValue == null) currentFeatureValue = ""; 139 }// End if 140 // Deal with Feature 141 if ("Feature".equals(elemName)){ 142 if(currentFeatureName == null){ 143 // Cannot add the (key,value) pair to the map 144 // One of them is null something was wrong in the XML file. 145 throw new GateSaxException("A feature name was empty." + 146 "The annotation that cause it is " + 147 currentAnnot + 148 ".Please check the document with a text editor before trying again."); 149 }else { 150 if (currentFeatureMap == null){ 151 // The XMl file was somehow altered and a start Feature wasn't found. 152 throw new GateSaxException("Document not consistent. A start"+ 153 " feature element is missing. " + 154 "The annotation that cause it is " + 155 currentAnnot + 156 "Please check the document with a text editor before trying again."); 157 }// End if 158 // Create the appropiate feature name and values 159 // If those object cannot be created, their string representation will 160 // be used. 161 currentFeatureMap.put(createFeatKey(),createFeatValue()); 162 // currentFeatureMap.put(currentFeatureName,currentFeatureValue); 163 // Reset current key 164 currentFeatureKeyClassName = null; 165 currentFeatureKeyItemClassName = null; 166 currentFeatureName = null; 167 // Reset current value 168 currentFeatureValueClassName = null; 169 currentFeatureValueItemClassName = null; 170 currentFeatureValue = null; 171 }// End if 172 // Reset the Name & Value pair. 173 currentFeatureName = null; 174 currentFeatureValue = null; 175 return; 176 }//End if 177 // Deal GateDocumentFeatures 178 if ("GateDocumentFeatures".equals(elemName)){ 179 if (currentFeatureMap == null) 180 currentFeatureMap = Factory.newFeatureMap(); 181 doc.setFeatures(currentFeatureMap); 182 currentFeatureMap = null; 183 return; 184 }// End if 185 186 // Deal with AnnotationSet 187 if ("AnnotationSet".equals(elemName)){ 188 // Create and add annotations to the currentAnnotationSet 189 Iterator iterator = colector.iterator(); 190 while (iterator.hasNext()){ 191 AnnotationObject annot = (AnnotationObject) iterator.next(); 192 // Clear the annot from the colector 193 iterator.remove(); 194 // Create a new annotation and add it to the annotation set 195 try{ 196 currentAnnotationSet.add(annot.getStart(), 197 annot.getEnd(), 198 annot.getElemName(), 199 annot.getFM()); 200 }catch (gate.util.InvalidOffsetException e){ 201 throw new GateSaxException(e); 202 }// End try 203 }// End while 204 // The colector is empty and ready for the next AnnotationSet 205 return; 206 }// End if 207 208 209 }//endElement 210 211 /** 212 * This method is called when the SAX parser encounts text in the XML doc. 213 * Here we calculate the end indices for all the elements present inside the 214 * stack and update with the new values. 215 */ 216 public void characters( char[] text,int start,int length) throws SAXException{ 217 // Create a string object based on the reported text 218 String content = new String(text, start, length); 219 if ("TextWithNodes".equals((String)currentElementStack.peek())){ 220 processTextOfTextWithNodesElement(content); 221 return; 222 }// End if 223 if ("Name".equals((String)currentElementStack.peek())){ 224 processTextOfNameElement(content); 225 return; 226 }// End if 227 if ("Value".equals((String)currentElementStack.peek())){ 228 //if (currentFeatureName != null && "string".equals(currentFeatureName) && 229 //currentAnnot!= null && "Token".equals(currentAnnot.getElemName()) && 230 //currentAnnot.getEnd().longValue() == 1063) 231 //System.out.println("Content=" + content + " start="+ start + " length=" + length); 232 processTextOfValueElement(content); 233 return; 234 }// End if 235 }//characters 236 237 /** 238 * This method is called when the SAX parser encounts white spaces 239 */ 240 public void ignorableWhitespace(char ch[],int start,int length) throws 241 SAXException{ 242 }//ignorableWhitespace 243 244 /** 245 * Error method.We deal with this exception inside SimpleErrorHandler class 246 */ 247 public void error(SAXParseException ex) throws SAXException { 248 // deal with a SAXParseException 249 // see SimpleErrorhandler class 250 _seh.error(ex); 251 }//error 252 253 /** 254 * FatalError method. 255 */ 256 public void fatalError(SAXParseException ex) throws SAXException { 257 // deal with a SAXParseException 258 // see SimpleErrorhandler class 259 _seh.fatalError(ex); 260 }//fatalError 261 262 /** 263 * Warning method comment. 264 */ 265 public void warning(SAXParseException ex) throws SAXException { 266 // deal with a SAXParseException 267 // see SimpleErrorhandler class 268 _seh.warning(ex); 269 }//warning 270 271 // Custom methods section 272 273 274 /** This method deals with a AnnotationSet element. */ 275 private void processAnnotationSetElement(Attributes atts){ 276 if (atts != null){ 277 for (int i = 0; i < atts.getLength(); i++) { 278 // Extract name and value 279 String attName = atts.getLocalName(i); 280 String attValue = atts.getValue(i); 281 if ("Name".equals(attName)) 282 currentAnnotationSet = doc.getAnnotations(attValue); 283 }// End for 284 }// End if 285 }//processAnnotationSetElement 286 287 /** This method deals with the start of a Name element*/ 288 private void processNameElement(Attributes atts){ 289 if (atts == null) return; 290 currentFeatureKeyClassName = atts.getValue("className"); 291 currentFeatureKeyItemClassName = atts.getValue("itemClassName"); 292 }// End processNameElement(); 293 294 /** This method deals with the start of a Value element*/ 295 private void processValueElement(Attributes atts){ 296 if (atts == null) return; 297 currentFeatureValueClassName = atts.getValue("className"); 298 currentFeatureValueItemClassName = atts.getValue("itemClassName"); 299 }// End processValueElement(); 300 301 /** This method deals with a Annotation element. */ 302 private void processAnnotationElement(Attributes atts){ 303 if (atts != null){ 304 currentAnnot = new AnnotationObject(); 305 for (int i = 0; i < atts.getLength(); i++) { 306 // Extract name and value 307 String attName = atts.getLocalName(i); 308 String attValue = atts.getValue(i); 309 310 if ("Type".equals(attName)) 311 currentAnnot.setElemName(attValue); 312 313 try{ 314 if ("StartNode".equals(attName)){ 315 Integer id = new Integer(attValue); 316 Long offset = (Long)id2Offset.get(id); 317 if (offset == null){ 318 throw new GateRuntimeException("Couldn't found Node with id = " + 319 id + 320 ".It was specified in annot " + 321 currentAnnot+ 322 " as a start node!" + 323 "Check the document with a text editor or something"+ 324 " before trying again."); 325 326 }else 327 currentAnnot.setStart(offset); 328 }// Endif 329 if ("EndNode".equals(attName)){ 330 Integer id = new Integer(attValue); 331 Long offset = (Long) id2Offset.get(id); 332 if (offset == null){ 333 throw new GateRuntimeException("Couldn't found Node with id = " + 334 id+ 335 ".It was specified in annot " + 336 currentAnnot+ 337 " as a end node!" + 338 "Check the document with a text editor or something"+ 339 " before trying again."); 340 }else 341 currentAnnot.setEnd(offset); 342 }// End if 343 } catch (NumberFormatException e){ 344 throw new GateRuntimeException("Offsets problems.Couldn't create"+ 345 " Integers from" + " id[" + 346 attValue + "]) in annot " + 347 currentAnnot+ 348 "Check the document with a text editor or something,"+ 349 " before trying again"); 350 }// End try 351 }// End For 352 }// End if 353 }//processAnnotationElement 354 355 /** This method deals with a Features element. */ 356 private void processFeatureElement(Attributes atts){ 357 // The first time feature is calle it will create a features map. 358 if (currentFeatureMap == null) 359 currentFeatureMap = Factory.newFeatureMap(); 360 }//processFeatureElement 361 362 /** This method deals with a Node element. */ 363 private void processNodeElement(Attributes atts){ 364 if (atts != null){ 365 for (int i = 0; i < atts.getLength(); i++) { 366 // Extract name and value 367 String attName = atts.getLocalName(i); 368 String attValue = atts.getValue(i); 369 //System.out.println("Node : " + attName + "=" +attValue); 370 if ("id".equals(attName)){ 371 try{ 372 Integer id = new Integer(attValue); 373 id2Offset.put(id,new Long(tmpDocContent.length())); 374 }catch(NumberFormatException e){ 375 throw new GateRuntimeException("Coudn't create a node from " + 376 attValue + " Expected an integer."); 377 }// End try 378 }// End if 379 }// End for 380 }// End if 381 }// processNodeElement(); 382 383 /** This method deals with a Text belonging to TextWithNodes element. */ 384 private void processTextOfTextWithNodesElement(String text){ 385 text = recoverNewLineSequence(text); 386 tmpDocContent.append(text); 387 }//processTextOfTextWithNodesElement 388 389 /** Restore new line as in the original document if needed */ 390 private String recoverNewLineSequence(String text) { 391 String result = text; 392 393 // check for new line 394 if(text.indexOf('\n') != -1) { 395 String newLineType = 396 (String) doc.getFeatures().get(GateConstants.DOCUMENT_NEW_LINE_TYPE); 397 398 if("LF".equalsIgnoreCase(newLineType)) { 399 newLineType = null; 400 } 401 402 // exit with the same text if the change isn't necessary 403 if(newLineType == null) return result; 404 405 String newLine = "\n"; 406 if("CRLF".equalsIgnoreCase(newLineType)) { 407 newLine = "\r\n"; 408 } 409 if("CR".equalsIgnoreCase(newLineType)) { 410 newLine = "\r"; 411 } 412 if("LFCR".equalsIgnoreCase(newLineType)) { 413 newLine = "\n\r"; 414 } 415 416 StringBuffer buff = new StringBuffer(text); 417 int index = text.lastIndexOf('\n'); 418 while(index != -1) { 419 buff.replace(index, index+1, newLine); 420 index = text.lastIndexOf('\n', index-1); 421 } // while 422 result = buff.toString(); 423 } // if 424 425 return result; 426 } // recoverNewLineSequence(String text) 427 428 /** This method deals with a Text belonging to Name element. */ 429 private void processTextOfNameElement(String text) throws GateSaxException{ 430 if (currentFeatureMap == null) 431 throw new GateSaxException("Gate xml format processing error:" + 432 " Found a Name element that is not enclosed into a Feature one while" + 433 " analyzing the annotation " + 434 currentAnnot + 435 "Please check the document with a text editor or something before" + 436 " trying again."); 437 else{ 438 // In the entities case, characters() gets called separately for each 439 // entity so the text needs to be appended. 440 if (currentFeatureName == null) 441 currentFeatureName = text; 442 else 443 currentFeatureName = currentFeatureName + text; 444 }// End If 445 }//processTextOfNameElement(); 446 447 /** This method deals with a Text belonging to Value element. */ 448 private void processTextOfValueElement(String text) throws GateSaxException{ 449 if (currentFeatureMap == null) 450 throw new GateSaxException("Gate xml format processing error:" + 451 " Found a Value element that is not enclosed into a Feature one while" + 452 " analyzing the annotation " + 453 currentAnnot+ 454 "Please check the document with a text editor or something before" + 455 " trying again."); 456 else{ 457 // In the entities case, characters() gets called separately for each 458 // entity so the text needs to be appended. 459 if (currentFeatureValue == null) 460 currentFeatureValue = text; 461 else 462 currentFeatureValue = currentFeatureValue + text; 463 }// End If 464 }//processTextOfValueElement(); 465 466 /** Creates a feature key using this information: 467 * currentFeatureKeyClassName, currentFeatureKeyItemClassName, 468 * currentFeatureName. See createFeatObject() method for more details. 469 */ 470 private Object createFeatKey(){ 471 return createFeatObject(currentFeatureKeyClassName, 472 currentFeatureKeyItemClassName, 473 currentFeatureName); 474 }//createFeatKey() 475 476 /** Creates a feature value using this information: 477 * currentFeatureValueClassName, currentFeatureValueItemClassName, 478 * currentFeatureValue. See createFeatObject() method for more details. 479 */ 480 private Object createFeatValue(){ 481 return createFeatObject(currentFeatureValueClassName, 482 currentFeatureValueItemClassName, 483 currentFeatureValue); 484 }//createFeatValue() 485 486 /** This method tries to reconstruct an object given its class name and its 487 * string representation. If the object is a Collection then the items 488 * from its string representation must be separated by a ";". In that 489 * case, the currentFeatureValueItemClassName is used to create items 490 * belonging to this class. 491 * @param aFeatClassName represents the name of the class of 492 * the feat object being created. If it is null then the javaLang.String will 493 * be used as default. 494 * @param aFeatItemClassName is it used only if aFeatClassName is a 495 * collection.If it is null then java.lang.String will be used as default; 496 * @param aFeatStringRepresentation sais it all 497 * @return an Object created from aFeatClassName and its 498 * aFeatStringRepresentation. If not possible, then aFeatStringRepresentation 499 * is returned. 500 * @throws GateRuntimeException If it can't create an item, that 501 * does not comply with its class definition, to add to the 502 * collection. 503 */ 504 private Object createFeatObject( String aFeatClassName, 505 String aFeatItemClassName, 506 String aFeatStringRepresentation){ 507 // If the string rep is null then the object will be null; 508 if (aFeatStringRepresentation == null) return null; 509 if (aFeatClassName == null) aFeatClassName = "java.lang.String"; 510 if (aFeatItemClassName == null) aFeatItemClassName = "java.lang.String"; 511 Class currentFeatClass = null; 512 try{ 513 currentFeatClass = Gate.getClassLoader().loadClass(aFeatClassName); 514 }catch (ClassNotFoundException cnfex){ 515 return aFeatStringRepresentation; 516 }// End try 517 if (java.util.Collection.class.isAssignableFrom(currentFeatClass)){ 518 Class itemClass = null; 519 Collection featObject = null; 520 try{ 521 featObject = (Collection) currentFeatClass.newInstance(); 522 try{ 523 itemClass = Gate.getClassLoader().loadClass(aFeatItemClassName); 524 }catch(ClassNotFoundException cnfex){ 525 Out.prln("Warning: Item class "+ aFeatItemClassName + " not found."+ 526 "Adding items as Strings to the feature called \"" + currentFeatureName 527 + "\" in the annotation " + currentAnnot); 528 itemClass = java.lang.String.class; 529 }// End try 530 // Let's detect if itemClass takes a constructor with a String as param 531 Class[] paramsArray = new Class[1]; 532 paramsArray[0] = java.lang.String.class; 533 Constructor itemConstructor = null; 534 boolean addItemAsString = false; 535 try{ 536 itemConstructor = itemClass.getConstructor(paramsArray); 537 }catch (NoSuchMethodException nsme){ 538 addItemAsString = true; 539 }catch (SecurityException se){ 540 addItemAsString = true; 541 }// End try 542 StringTokenizer strTok = new StringTokenizer( 543 aFeatStringRepresentation,";"); 544 Object[] params = new Object[1]; 545 Object itemObj = null; 546 while (strTok.hasMoreTokens()){ 547 String itemStrRep = strTok.nextToken(); 548 if (addItemAsString) featObject.add(itemStrRep); 549 else{ 550 params[0] = itemStrRep; 551 try{ 552 itemObj = itemConstructor.newInstance(params); 553 }catch (Exception e){ 554 throw new GateRuntimeException("An item("+ 555 itemStrRep + 556 ") does not comply with its class" + 557 " definition("+aFeatItemClassName+").Happened while tried to"+ 558 " add feature: " + 559 aFeatStringRepresentation + " to the annotation " + currentAnnot); 560 }// End try 561 featObject.add(itemObj); 562 }// End if 563 }// End while 564 }catch(InstantiationException instex ){ 565 return aFeatStringRepresentation; 566 }catch (IllegalAccessException iae){ 567 return aFeatStringRepresentation; 568 }// End try 569 return featObject; 570 }// End if 571 // If currentfeatClass is not a Collection,test to see if 572 // it has a constructor that takes a String as param 573 Class[] params = new Class[1]; 574 params[0] = java.lang.String.class; 575 try{ 576 Constructor featConstr = currentFeatClass.getConstructor(params); 577 Object[] featConstrParams = new Object[1]; 578 featConstrParams[0] = aFeatStringRepresentation; 579 Object featObject = featConstr.newInstance(featConstrParams); 580 return featObject; 581 } catch(Exception e){ 582 return aFeatStringRepresentation; 583 }// End try 584 }// createFeatObject() 585 586 /** 587 * This method is called when the SAX parser encounts a comment 588 * It works only if the XmlDocumentHandler implements a 589 * com.sun.parser.LexicalEventListener 590 */ 591 public void comment(String text) throws SAXException { 592 }//comment 593 594 /** 595 * This method is called when the SAX parser encounts a start of a CDATA 596 * section 597 * It works only if the XmlDocumentHandler implements a 598 * com.sun.parser.LexicalEventListener 599 */ 600 public void startCDATA()throws SAXException { 601 }//startCDATA 602 603 /** 604 * This method is called when the SAX parser encounts the end of a CDATA 605 * section. 606 * It works only if the XmlDocumentHandler implements a 607 * com.sun.parser.LexicalEventListener 608 */ 609 public void endCDATA() throws SAXException { 610 }//endCDATA 611 612 /** 613 * This method is called when the SAX parser encounts a parsed Entity 614 * It works only if the XmlDocumentHandler implements a 615 * com.sun.parser.LexicalEventListener 616 */ 617 public void startParsedEntity(String name) throws SAXException { 618 }//startParsedEntity 619 620 /** 621 * This method is called when the SAX parser encounts a parsed entity and 622 * informs the application if that entity was parsed or not 623 * It's working only if the CustomDocumentHandler implements a 624 * com.sun.parser.LexicalEventListener 625 */ 626 public void endParsedEntity(String name, boolean included)throws SAXException{ 627 }//endParsedEntity 628 629 //StatusReporter Implementation 630 631 /** 632 * This methos is called when a listener is registered with this class 633 */ 634 public void addStatusListener(StatusListener listener){ 635 myStatusListeners.add(listener); 636 }//addStatusListener 637 /** 638 * This methos is called when a listener is removed 639 */ 640 public void removeStatusListener(StatusListener listener){ 641 myStatusListeners.remove(listener); 642 }//removeStatusListener 643 /** 644 * This methos is called whenever we need to inform the listener about an 645 * event. 646 */ 647 protected void fireStatusChangedEvent(String text){ 648 Iterator listenersIter = myStatusListeners.iterator(); 649 while(listenersIter.hasNext()) 650 ((StatusListener)listenersIter.next()).statusChanged(text); 651 }//fireStatusChangedEvent 652 653 // XmlDocumentHandler member data 654 655 /** This constant indicates when to fire the status listener. 656 * This listener will add an overhead and we don't want a big overhead. 657 * It will be callled from ELEMENTS_RATE to ELEMENTS_RATE 658 */ 659 final static int ELEMENTS_RATE = 128; 660 661 /** This object indicates what to do when the parser encounts an error */ 662 private SimpleErrorHandler _seh = new SimpleErrorHandler(); 663 664 /** The content of the XML document, without any tag */ 665 private StringBuffer tmpDocContent = new StringBuffer(""); 666 667 /** A gate document */ 668 private gate.Document doc = null; 669 670 /** Listeners for status report */ 671 protected List myStatusListeners = new LinkedList(); 672 673 /** This reports the the number of elements that have beed processed so far*/ 674 private int elements = 0; 675 676 /** We need a colection to retain all the CustomObjects that will be 677 * transformed into annotation over the gate document... 678 * At the end of every annotation set read the objects in the colector are 679 * transformed into annotations... 680 */ 681 private List colector = null; 682 /** Maps nodes Ids to their offset in the document text. Those offsets will 683 * be used when creating annotations 684 */ 685 private Map id2Offset = new TreeMap(); 686 /** Holds the current element read.*/ 687 private Stack currentElementStack = new Stack(); 688 /** This inner objects maps an annotation object. When an annotation from the 689 * xml document was read this structure is filled out 690 */ 691 private AnnotationObject currentAnnot = null; 692 /** A map holding current annotation's features*/ 693 private FeatureMap currentFeatureMap = null; 694 /** A key of the current feature*/ 695 private String currentFeatureName = null; 696 /** The value of the current feature*/ 697 private String currentFeatureValue = null; 698 /** The class name of the key in the current feature*/ 699 private String currentFeatureKeyClassName = null; 700 /** If the key is a collection then we need to know the class name of the 701 * items present in this collection. The next field holds just that. 702 */ 703 private String currentFeatureKeyItemClassName = null; 704 /** The class name for the value in the current feature*/ 705 private String currentFeatureValueClassName = null; 706 /** If the value is a collection then we need to know the class name of the 707 * items present in this collection. The next field holds just that. 708 */ 709 private String currentFeatureValueItemClassName = null; 710 /** the current annotation set that is being created and filled with 711 * annotations 712 */ 713 private AnnotationSet currentAnnotationSet = null; 714 715 /** An inner class modeling the information contained by an annotation.*/ 716 class AnnotationObject { 717 /** Constructor */ 718 public AnnotationObject(){}//AnnotationObject 719 /** Accesor for the annotation type modeled here as ElemName */ 720 public String getElemName(){ 721 return elemName; 722 }//getElemName 723 /** Accesor for the feature map*/ 724 public FeatureMap getFM(){ 725 return fm; 726 }// getFM() 727 /** Accesor for the start ofset*/ 728 public Long getStart(){ 729 return start; 730 }// getStart() 731 /** Accesor for the end offset*/ 732 public Long getEnd(){ 733 return end; 734 }// getEnd() 735 /** Mutator for the annotation type */ 736 public void setElemName(String anElemName){ 737 elemName = anElemName; 738 }// setElemName(); 739 /** Mutator for the feature map*/ 740 public void setFM(FeatureMap aFm){ 741 fm = aFm; 742 }// setFM(); 743 /** Mutator for the start offset*/ 744 public void setStart(Long aStart){ 745 start = aStart; 746 }// setStart(); 747 /** Mutator for the end offset*/ 748 public void setEnd(Long anEnd){ 749 end = anEnd; 750 }// setEnd(); 751 752 public String toString(){ 753 return " [type=" + elemName + 754 " startNode=" + start+ 755 " endNode=" + end+ 756 " features="+ fm +"] "; 757 } 758 // Data fields 759 private String elemName = null; 760 private FeatureMap fm = null; 761 private Long start = null; 762 private Long end = null; 763 } // AnnotationObject 764 }//GateFormatXmlDocumentHandler 765 766
|
GateFormatXmlDocumentHandler |
|