|
EmailDocumentHandler |
|
1 /* 2 * EmailDocumentHandler.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, 3/Aug/2000 12 * 13 * $Id: EmailDocumentHandler.java,v 1.24 2001/11/08 17:23:31 cursu Exp $ 14 */ 15 16 package gate.email; 17 18 import java.util.*; 19 import java.io.*; 20 21 import gate.corpora.*; 22 import gate.util.*; 23 import gate.*; 24 import gate.event.*; 25 26 import junit.framework.*; 27 28 /** 29 * This class implements the behaviour of the Email reader 30 * It takes the Gate Document representing a list with e-mails and 31 * creates Gate annotations on it. 32 */ 33 public class EmailDocumentHandler{ 34 35 /** Debug flag */ 36 private static final boolean DEBUG = false; 37 38 private String content = null; 39 private long documentSize = 0; 40 41 /** 42 * Constructor used in tests mostly 43 */ 44 public EmailDocumentHandler() { 45 setUp(); 46 }//EmailDocumentHandler 47 48 /** 49 * Constructor initialises some private fields 50 */ 51 public EmailDocumentHandler( gate.Document aGateDocument, 52 Map aMarkupElementsMap, 53 Map anElement2StringMap 54 ) { 55 56 gateDocument = aGateDocument; 57 58 // gets AnnotationSet based on the new gate document 59 if (basicAS == null) 60 basicAS = gateDocument.getAnnotations( 61 GateConstants.ORIGINAL_MARKUPS_ANNOT_SET_NAME); 62 63 markupElementsMap = aMarkupElementsMap; 64 element2StringMap = anElement2StringMap; 65 setUp(); 66 }// EmailDocumentHandler 67 68 /** 69 * Reads the Gate Document line by line and does the folowing things: 70 * <ul> 71 * <li> Each line is analized in order to detect where an e-mail starts. 72 * <li> If the line belongs to an e-mail header then creates the 73 * annotation if the markupElementsMap allows that. 74 * <li> Lines belonging to the e-mail body are placed under a Gate 75 * annotation called messageBody. 76 * </ul> 77 */ 78 public void annotateMessages() throws IOException, 79 gate.util.InvalidOffsetException { 80 // obtain a BufferedReader form the Gate document... 81 BufferedReader gateDocumentReader = null; 82 // Get the string representing the content of the document 83 // It is used inside CreateAnnotation method 84 content = gateDocument.getContent().toString(); 85 // Get the sieze of the Gate Document. For the same purpose. 86 documentSize = gateDocument.getContent().size().longValue(); 87 88 // gateDocumentReader = new BufferedReader(new InputStreamReader( 89 // gateDocument.getSourceUrl().openConnection().getInputStream())); 90 gateDocumentReader = new BufferedReader(new InputStreamReader( 91 new ByteArrayInputStream(content.getBytes()))); 92 93 // for each line read from the gateDocumentReader do 94 // if the line begins an e-mail message then fire a status listener, mark 95 // that we are processing an e-mail, update the cursor and go to the next 96 // line. 97 98 // if we are inside an e-mail, test if the line belongs to the message 99 // header 100 // if so, create a header field annotation. 101 102 // if we are inside a a body and this is the first line from the body, 103 // create the message body annotation. 104 // Otherwise just update the cursor and go to the next line 105 106 // if the line doesn't belong to an e-mail message then just update the 107 // cursor. 108 // next line 109 110 String line = null; 111 String aFieldName = null; 112 113 long cursor = 0; 114 long endEmail = 0; 115 long startEmail = 0; 116 long endHeader = 0; 117 long startHeader = 0; 118 long endBody = 0; 119 long startBody = 0; 120 long endField = 0; 121 long startField = 0; 122 123 boolean insideAnEmail = false; 124 boolean insideHeader = false; 125 boolean insideBody = false; 126 boolean emailReadBefore = false; 127 boolean fieldReadBefore = false; 128 129 long nlSize = detectNLSize(); 130 131 //Out.println("NL SIZE = " + nlSize); 132 133 // read each line from the reader 134 while ((line = gateDocumentReader.readLine()) != null){ 135 // Here we test if the line delimitates two e-mail messages. 136 // Each e-mail message begins with a line like this: 137 // From P.Fairhurst Thu Apr 18 12:22:23 1996 138 // Method lineBeginsMessage() detects such lines. 139 if (lineBeginsMessage(line)){ 140 // Inform the status listener to fire only 141 // if no. of elements processed. 142 // So far is a multiple of ELEMENTS_RATE 143 if ((++ emails % EMAILS_RATE) == 0) 144 fireStatusChangedEvent("Reading emails : " + emails); 145 // if there are e-mails read before, then the previous e-mail 146 // ends here. 147 if (true == emailReadBefore){ 148 // Cursor points at the beggining of the line 149 // E-mail and Body ends before the \n char 150 // Email ends as cursor value indicates 151 endEmail = cursor - nlSize ; 152 // also the e-mail body ends when an e-mail ends 153 endBody = cursor - nlSize; 154 //Annotate an E-mail body (startBody, endEmail) 155 createAnnotation("Body",startBody,endBody,null); 156 //Annotate an E-mail message(startEmail, endEmail) Email starts 157 createAnnotation("Message",startEmail,endEmail,null); 158 } 159 // if no e-mail was read before, now there is at list one message 160 // read 161 emailReadBefore = true; 162 // E-mail starts imediately from the beginning of this line which 163 // sepatates 2 messages. 164 startEmail = cursor; 165 // E-mail header starts also from here 166 startHeader = cursor; 167 // The cursor is updated with the length of the line + the 168 // new line char 169 cursor += line.length() + nlSize; 170 // We are inside an e-mail 171 insideAnEmail = true; 172 // Next is the E-mail header 173 insideHeader = true; 174 // No field inside header has been read before 175 fieldReadBefore = false; 176 // Read the next line 177 continue; 178 }//if (lineBeginsMessage(line)) 179 if (false == insideAnEmail){ 180 // the cursor is update with the length of the line + 181 // the new line char 182 cursor += line.length() + nlSize; 183 // read the next line 184 continue; 185 }//if 186 // here we are inside an e-mail message (inside Header or Body) 187 if (true == insideHeader){ 188 // E-mail spec sais that E-mail header is separated by E-mail body 189 // by a \n char 190 if (line.equals("")){ 191 // this \n sepatates the header of an e-mail form its body 192 // If we are here it means that the header has ended. 193 insideHeader = false; 194 // e-mail header ends here 195 endHeader = cursor - nlSize; 196 // update the cursor with the length of \n 197 cursor += line.length() + nlSize; 198 // E-mail body starts from here 199 startBody = cursor; 200 // if fields were read before, it means that the e-mail has a header 201 if (true == fieldReadBefore){ 202 endField = endHeader; 203 //Create a field annotation (fieldName, startField, endField) 204 createAnnotation(aFieldName, startField, endField, null); 205 //Create an e-mail header annotation 206 createAnnotation("Header",startHeader,endHeader,null); 207 }//if 208 // read the next line 209 continue; 210 }//if (line.equals("")) 211 // if line begins with a field then prepare to create an 212 // annotation with the name of the field 213 if (lineBeginsWithField(line)){ 214 // if a field was read before, it means that the previous field ends 215 // here 216 if (true == fieldReadBefore){ 217 // the previous field end here 218 endField = cursor - nlSize; 219 //Create a field annotation (fieldName, startField, endField) 220 createAnnotation(aFieldName, startField, endField, null); 221 }//if 222 fieldReadBefore = true; 223 aFieldName = getFieldName(); 224 startField = cursor + aFieldName.length() + ":".length(); 225 }//if 226 // in both cases the cursor is updated and read the next line 227 // the cursor is update with the length of the line + 228 // the new line char 229 cursor += line.length() + nlSize; 230 // read the next line 231 continue; 232 }//if (true == insideHeader) 233 // here we are inside the E-mail body 234 // the body will end when the e-mail will end. 235 // here we just update the cursor 236 cursor += line.length() + nlSize; 237 }//while 238 // it might be possible that the file to contain only one e-mail and 239 // if the file contains only one e-mail message then the variable 240 // emailReadBefore must be set on true value 241 if (true == emailReadBefore){ 242 endBody = cursor - nlSize; 243 endEmail = cursor - nlSize; 244 //Annotate an E-mail body (startBody, endEmail) 245 createAnnotation("Body",startBody,endBody,null); 246 //Annotate an E-mail message(startEmail, endEmail) Email starts 247 createAnnotation("Message",startEmail,endEmail,null); 248 } 249 // if emailReadBefore is not set on true, that means that we didn't 250 // encounter any line like this: 251 // From P.Fairhurst Thu Apr 18 12:22:23 1996 252 }//annotateMessages 253 254 /** 255 * This method detects if the text file which contains e-mail messages 256 * is under MSDOS or UNIX format. 257 * Under MSDOS the size of NL is 2 (\n \r) and under UNIX (\n) the size is 1 258 * @return the size of the NL (1,2 or 0 = if no \n is found) 259 */ 260 private int detectNLSize() { 261 262 // get a char array 263 char[] document = null; 264 265 // transform the gate Document into a char array 266 document = gateDocument.getContent().toString().toCharArray(); 267 268 // search for the \n char 269 // when it is found test if is followed by the \r char 270 for (int i=0; i<document.length; i++){ 271 if (document[i] == '\n'){ 272 273 // we just found a \n char. 274 // here we test if is followed by a \r char or preceded by a \r char 275 if ( 276 (((i+1) < document.length) && (document[i+1] == '\r')) 277 || 278 (((i-1) >= 0) && (document[i-1] == '\r')) 279 ) return 2; 280 else return 1; 281 } 282 } 283 //if no \n char is found then the document is contained into a single text 284 // line. 285 return 0; 286 287 } // detectNLSize 288 289 /** 290 * This method creates a gate annotation given its name, start, end and 291 * feature map. 292 */ 293 private void createAnnotation(String anAnnotationName, long anAnnotationStart, 294 long anAnnotationEnd, FeatureMap aFeatureMap) 295 throws gate.util.InvalidOffsetException{ 296 297 /* 298 while (Character.isWhitespace(content.charAt((int) anAnnotationStart))) 299 anAnnotationStart ++; 300 301 // System.out.println(content.charAt((int) anAnnotationEnd)); 302 while (Character.isWhitespace(content.charAt((int) anAnnotationEnd))) 303 anAnnotationEnd --; 304 305 anAnnotationEnd ++; 306 */ 307 if (canCreateAnnotation(anAnnotationStart,anAnnotationEnd,documentSize)){ 308 if (aFeatureMap == null) 309 aFeatureMap = Factory.newFeatureMap(); 310 basicAS.add( new Long(anAnnotationStart), 311 new Long(anAnnotationEnd), 312 anAnnotationName.toLowerCase(), 313 aFeatureMap); 314 }// End if 315 }//createAnnotation 316 /** 317 * This method verifies if an Annotation can be created. 318 */ 319 private boolean canCreateAnnotation(long start, 320 long end, 321 long gateDocumentSize){ 322 323 if (start < 0 || end < 0 ) return false; 324 if (start > end ) return false; 325 if ((start > gateDocumentSize) || (end > gateDocumentSize)) return false; 326 return true; 327 }// canCreateAnnotation 328 329 /** 330 * Tests if the line begins an e-mail message 331 * @param aTextLine a line from the file containing the e-mail messages 332 * @return true if the line begins an e-mail message 333 * @return false if is doesn't 334 */ 335 private boolean lineBeginsMessage(String aTextLine){ 336 int score = 0; 337 338 // if first token is "From" and the rest contains Day, Zone, etc 339 // then this line begins a message 340 // create a new String Tokenizer with " " as separator 341 StringTokenizer tokenizer = new StringTokenizer(aTextLine," "); 342 343 // get the first token 344 String firstToken = null; 345 if (tokenizer.hasMoreTokens()) 346 firstToken = tokenizer.nextToken(); 347 else return false; 348 349 // trim it 350 firstToken.trim(); 351 352 // check against "From" word 353 // if the first token is not From then the entire line can not begin 354 // a message. 355 if (!firstToken.equals("From")) 356 return false; 357 358 // else continue the analize 359 while (tokenizer.hasMoreTokens()){ 360 361 // get the next token 362 String token = tokenizer.nextToken(); 363 token.trim(); 364 365 // see if it has a meaning(analize if is a Day, Month,Zone, Time, Year ) 366 if (hasAMeaning(token)) 367 score += 1; 368 } 369 370 // a score greather or equql with 5 means that this line begins a message 371 if (score >= 5) return true; 372 else return false; 373 374 } // lineBeginsMessage 375 376 /** 377 * Tests if the line begins with a field from the e-mail header 378 * If the answer is true then it also sets the member fieldName with the 379 * value of this e-mail header field. 380 * @param aTextLine a line from the file containing the e-mail text 381 * @return true if the line begins with a field from the e-mail header 382 * @return false if is doesn't 383 */ 384 private boolean lineBeginsWithField(String aTextLine){ 385 if (containsSemicolon(aTextLine)){ 386 StringTokenizer tokenizer = new StringTokenizer(aTextLine,":"); 387 388 // get the first token 389 String firstToken = null; 390 391 if (tokenizer.hasMoreTokens()) 392 firstToken = tokenizer.nextToken(); 393 else return false; 394 395 if (firstToken != null){ 396 // trim it 397 firstToken.trim(); 398 if (containsWhiteSpaces(firstToken)) return false; 399 400 // set the member field 401 fieldName = firstToken; 402 } 403 return true; 404 } else return false; 405 406 } // lineBeginsWithField 407 408 /** 409 * This method checks if a String contains white spaces. 410 */ 411 private boolean containsWhiteSpaces(String aString) { 412 for (int i = 0; i<aString.length(); i++) 413 if (Character.isWhitespace(aString.charAt(i))) return true; 414 return false; 415 } // containsWhiteSpaces 416 417 /** 418 * This method checks if a String contains a semicolon char 419 */ 420 private boolean containsSemicolon(String aString) { 421 for (int i = 0; i<aString.length(); i++) 422 if (aString.charAt(i) == ':') return true; 423 return false; 424 } // containsSemicolon 425 426 /** 427 * This method tests a token if is Day, Month, Zone, Time, Year 428 */ 429 private boolean hasAMeaning(String aToken) { 430 // if token is a Day return true 431 if (day.contains(aToken)) return true; 432 433 // if token is a Month return true 434 if (month.contains(aToken)) return true; 435 436 // if token is a Zone then return true 437 if (zone.contains(aToken)) return true; 438 439 // test if is a day number or a year 440 Integer dayNumberOrYear = null; 441 try{ 442 dayNumberOrYear = new Integer(aToken); 443 } catch (NumberFormatException e){ 444 dayNumberOrYear = null; 445 } 446 447 // if the creation succeded, then test if is day or year 448 if (dayNumberOrYear != null) { 449 int number = dayNumberOrYear.intValue(); 450 451 // if is a number between 1 and 31 then is a day 452 if ((number > 0) && (number < 32)) return true; 453 454 // if is a number between 1900 si 3000 then is a year ;)) 455 if ((number > 1900) && (number < 3000)) return true; 456 457 // it might be the last two digits of 19xx 458 if ((number >= 0) && (number <= 99)) return true; 459 } 460 // test if is time: hh:mm:ss 461 if (isTime(aToken)) return true; 462 463 return false; 464 } // hasAMeaning 465 466 /** 467 * Tests a token if is in time format HH:MM:SS 468 */ 469 private boolean isTime(String aToken) { 470 StringTokenizer st = new StringTokenizer(aToken,":"); 471 472 // test each token if is hour, minute or second 473 String hourString = null; 474 if (st.hasMoreTokens()) 475 hourString = st.nextToken(); 476 477 // if there are no more tokens, it means that is not a time 478 if (hourString == null) return false; 479 480 // test if is a number between 0 and 23 481 Integer hourInteger = null; 482 try{ 483 hourInteger = new Integer(hourString); 484 } catch (NumberFormatException e){ 485 hourInteger = null; 486 } 487 if (hourInteger == null) return false; 488 489 // if is not null then it means is a number 490 // test if is in 0 - 23 range 491 // if is not in this range then is not an hour 492 int hour = hourInteger.intValue(); 493 if ( (hour < 0) || (hour > 23) ) return false; 494 495 // we have the hour 496 // now repeat the test for minute and seconds 497 498 // minutes 499 String minutesString = null; 500 if (st.hasMoreTokens()) 501 minutesString = st.nextToken(); 502 503 // if there are no more tokens (minutesString == null) then return false 504 if (minutesString == null) return false; 505 506 // test if is a number between 0 and 59 507 Integer minutesInteger = null; 508 try { 509 minutesInteger = new Integer (minutesString); 510 } catch (NumberFormatException e){ 511 minutesInteger = null; 512 } 513 514 if (minutesInteger == null) return false; 515 516 // if is not null then it means is a number 517 // test if is in 0 - 59 range 518 // if is not in this range then is not a minute 519 int minutes = minutesInteger.intValue(); 520 if ( (minutes < 0) || (minutes > 59) ) return false; 521 522 // seconds 523 String secondsString = null; 524 if (st.hasMoreTokens()) 525 secondsString = st.nextToken(); 526 527 // if there are no more tokens (secondsString == null) then return false 528 if (secondsString == null) return false; 529 530 // test if is a number between 0 and 59 531 Integer secondsInteger = null; 532 try { 533 secondsInteger = new Integer (secondsString); 534 } catch (NumberFormatException e){ 535 secondsInteger = null; 536 } 537 if (secondsInteger == null) return false; 538 539 // if is not null then it means is a number 540 // test if is in 0 - 59 range 541 // if is not in this range then is not a minute 542 int seconds = secondsInteger.intValue(); 543 if ( (seconds < 0) || (seconds > 59) ) return false; 544 545 // if there are more tokens in st it means that we don't have this format: 546 // HH:MM:SS 547 if (st.hasMoreTokens()) return false; 548 549 // if we are here it means we have a time 550 return true; 551 }// isTime 552 553 /** 554 * Initialises the collections with data used by method lineBeginsMessage() 555 */ 556 private void setUp(){ 557 day = new HashSet(); 558 day.add("Mon"); 559 day.add("Tue"); 560 day.add("Wed"); 561 day.add("Thu"); 562 day.add("Fri"); 563 day.add("Sat"); 564 day.add("Sun"); 565 566 month = new HashSet(); 567 month.add("Jan"); 568 month.add("Feb"); 569 month.add("Mar"); 570 month.add("Apr"); 571 month.add("May"); 572 month.add("Jun"); 573 month.add("Jul"); 574 month.add("Aug"); 575 month.add("Sep"); 576 month.add("Oct"); 577 month.add("Nov"); 578 month.add("Dec"); 579 580 zone = new HashSet(); 581 zone.add("UT"); 582 zone.add("GMT"); 583 zone.add("EST"); 584 zone.add("EDT"); 585 zone.add("CST"); 586 zone.add("CDT"); 587 zone.add("MST"); 588 zone.add("MDT"); 589 zone.add("PST"); 590 zone.add("PDT"); 591 }//setUp 592 593 /** 594 * This method returns the value of the member fieldName. 595 * fieldName is set by the method lineBeginsWithField(String line). 596 * Each time the the line begins with a field name, that fiels will be stored 597 * in this member. 598 */ 599 private String getFieldName() { 600 if (fieldName == null) return new String(""); 601 else return fieldName; 602 } // getFieldName 603 604 // StatusReporter Implementation 605 606 /** 607 * This methos is called when a listener is registered with this class 608 */ 609 public void addStatusListener(StatusListener listener){ 610 myStatusListeners.add(listener); 611 } 612 /** 613 * This methos is called when a listener is removed 614 */ 615 public void removeStatusListener(StatusListener listener){ 616 myStatusListeners.remove(listener); 617 } 618 619 /** 620 * This methos is called whenever we need to inform the listener 621 * about an event. 622 */ 623 protected void fireStatusChangedEvent(String text){ 624 Iterator listenersIter = myStatusListeners.iterator(); 625 while(listenersIter.hasNext()) 626 ((StatusListener)listenersIter.next()).statusChanged(text); 627 } 628 629 private static final int EMAILS_RATE = 16; 630 631 // the content of the e-mail document, without any tag 632 // for internal use 633 private String tmpDocContent = null; 634 635 // a gate document 636 private gate.Document gateDocument = null; 637 638 // an annotation set used for creating annotation reffering the doc 639 private gate.AnnotationSet basicAS = null; 640 641 // this map marks the elements that we don't want to create annotations 642 private Map markupElementsMap = null; 643 644 // this map marks the elements after we want to insert some strings 645 private Map element2StringMap = null; 646 647 // listeners for status report 648 protected List myStatusListeners = new LinkedList(); 649 650 // this reports the the number of emails that have beed processed so far 651 private int emails = 0; 652 653 // this is set by the method lineBeginsWithField(String line) 654 // each time the the line begins with a field name, that fiels will be stored 655 // in this member. 656 private String fieldName = null; 657 658 private Collection day = null; 659 private Collection month = null; 660 private Collection zone = null; 661 662 663 // TEST SECTION 664 665 /** 666 * Test containsSemicolon 667 */ 668 private void testContainsSemicolon() { 669 String str1 = "X-Sender: oana@derwent"; 670 String str2 = "X-Sender oana@derwent"; 671 String str3 = ":X-Sender oana@derwent"; 672 String str4 = "X-Sender oana@derwent:"; 673 674 Assert.assertTrue((containsSemicolon(str1) == true)); 675 Assert.assertTrue((containsSemicolon(str2)== false)); 676 Assert.assertTrue((containsSemicolon(str3) == true)); 677 Assert.assertTrue((containsSemicolon(str4) == true)); 678 }// testContainsSemicolon 679 680 /** 681 * Test containsWhiteSpaces 682 */ 683 private void testContainsWhiteSpaces(){ 684 String str1 = "Content-Type: TEXT/PLAIN; charset=US-ASCII"; 685 String str2 = "Content-Type:TEXT/PLAIN;charset=US-ASCII"; 686 String str3 = " Content-Type:TEXT/PLAIN;charset=US-ASCII"; 687 String str4 = "Content-Type:TEXT/PLAIN;charset=US-ASCII "; 688 689 Assert.assertTrue((containsWhiteSpaces(str1) == true)); 690 Assert.assertTrue((containsWhiteSpaces(str2) == false)); 691 Assert.assertTrue((containsWhiteSpaces(str3) == true)); 692 Assert.assertTrue((containsWhiteSpaces(str4) == true)); 693 }// testContainsWhiteSpaces 694 695 /** 696 * Test hasAMeaning 697 */ 698 private void testHasAMeaning() { 699 String str1 = "12:05:22"; 700 String str2 = "Sep"; 701 String str3 = "Fri"; 702 String str4 = "2000"; 703 String str5 = "GMT"; 704 String str6 = "Date: Wed, 13 Sep 2000 13:05:22 +0100 (BST)"; 705 String str7 = "12:75:22"; 706 String str8 = "September"; 707 String str9 = "Friday"; 708 709 Assert.assertTrue((hasAMeaning(str1) == true)); 710 Assert.assertTrue((hasAMeaning(str2) == true)); 711 Assert.assertTrue((hasAMeaning(str3) == true)); 712 Assert.assertTrue((hasAMeaning(str4) == true)); 713 Assert.assertTrue((hasAMeaning(str5) == true)); 714 Assert.assertTrue((hasAMeaning(str6) == false)); 715 Assert.assertTrue((hasAMeaning(str7) == false)); 716 Assert.assertTrue((hasAMeaning(str8) == false)); 717 Assert.assertTrue((hasAMeaning(str9) == false)); 718 } // testHasAMeaning 719 720 /** 721 * Test isTime 722 */ 723 private void testIsTime() { 724 String str1 = "13:05:22"; 725 String str2 = "13/05/22"; 726 String str3 = "24:05:22"; 727 728 Assert.assertTrue((isTime(str1) == true)); 729 Assert.assertTrue((isTime(str2) == false)); 730 Assert.assertTrue((isTime(str3) == false)); 731 }// testIsTime 732 733 /** 734 * Test lineBeginsMessage 735 */ 736 private void testLineBeginsMessage(){ 737 String str1 = "From oana@dcs.shef.ac.uk Wed Sep 13 13:05:23 2000"; 738 String str2 = "Date: Wed, 13 Sep 2000 13:05:22 +0100 (BST)"; 739 String str3 = "From oana@dcs.shef.ac.uk Sep 13 13:05:23 2000"; 740 741 Assert.assertTrue((lineBeginsMessage(str1) == true)); 742 Assert.assertTrue((lineBeginsMessage(str2) == false)); 743 Assert.assertTrue((lineBeginsMessage(str3) == false)); 744 745 }// testLineBeginsMessage 746 747 /** 748 * Test lineBeginsWithField 749 */ 750 private void testLineBeginsWithField() { 751 String str1 = "Message-ID: <Pine.SOL.3.91.1000913130311.19537A-10@derwent>"; 752 String str2 = "%:ContentType TEXT/PLAIN; charset=US-ASCII"; 753 754 Assert.assertTrue((lineBeginsWithField(str1) == true)); 755 Assert.assertTrue((lineBeginsWithField(str2) == true)); 756 }// testLineBeginsWithField 757 758 /** 759 * Test final 760 */ 761 public void testSelf(){ 762 testContainsSemicolon(); 763 testContainsWhiteSpaces(); 764 testHasAMeaning(); 765 testIsTime(); 766 testLineBeginsMessage(); 767 testLineBeginsWithField(); 768 } // testSelf 769 770 } //EmailDocumentHandler 771
|
EmailDocumentHandler |
|