001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 */ 021package org.biojava.bio.seq.io.agave; 022import java.io.IOException; 023import java.io.PrintStream; 024import java.io.PrintWriter; 025import java.util.Iterator; 026 027import org.biojava.bio.Annotatable; 028import org.biojava.bio.seq.ComponentFeature; 029import org.biojava.bio.seq.Feature; 030import org.biojava.bio.seq.FeatureHolder; 031import org.biojava.bio.seq.Sequence; 032import org.biojava.bio.seq.SimpleAssembly; 033import org.biojava.bio.seq.StrandedFeature; 034import org.biojava.bio.seq.impl.SimpleSequence; 035 036/** 037 * Writes Sequence into AGAVE XML document. The AGAVE 038 * format is defined in agave.dtd which can be downloaded 039 * from http://www.agavexml.org. 040 * 041 * @author Hanning Ni 042 * @author Brian King 043 */ 044public class AgaveWriter 045{ 046 /** 047 * Implements indenting for elements. 048 * @author Brian King 049 */ 050 protected class Indent 051 { 052 /** Base indent */ 053 protected String mIndent = new String(INDENT); 054 055 /** 056 * Add a level of indentation 057 */ 058 public void 059 indent() 060 { 061 mIndent += INDENT; 062 } 063 064 /** 065 * Remove a level of indentation 066 * 067 */ 068 public void 069 unIndent() 070 { 071 int len = mIndent.length(); 072 int iLen = INDENT.length(); 073 if(len >= iLen) 074 { 075 mIndent = mIndent.substring(0, len - iLen); 076 } 077 } 078 079 /** 080 * Return the current indent 081 * 082 */ 083 public String 084 toString() 085 { 086 return mIndent; 087 } 088 } 089 090 /** use a two space indent */ 091 public static final String INDENT = " "; 092 093 /** Write to XML document */ 094 protected PrintWriter mOut; 095 096 /** indent */ 097 protected Indent mIndent; 098 099 /** writes PCDATA replacing XML characters with escape entities */ 100 protected PCDATAFilterWriter mFilter; 101 102 /** 103 * The AnnotationMap to use for getting 104 * AGAVE XML attributes from a Sequence Annotation. 105 */ 106 protected AGAVEAnnotFilter mAnnotFilter; 107 108 /** write DOCTYPE if true */ 109 protected boolean mWriteDocType = true; 110 111 /** 112 * Default constructor uses generic annotation to attribute mapping. 113 * 114 */ 115 public AgaveWriter() 116 { 117 mAnnotFilter = SimpleAnnotFilter.SIMPLE_ANNOT_FILTER_FACTORY.getInstance(); 118 mIndent = new Indent(); 119 } 120 121 /** 122 * Construct with data source specific annotation to attribute 123 * mapping. 124 * 125 */ 126 public AgaveWriter(AGAVEAnnotFilter filter) 127 { 128 mAnnotFilter = filter; 129 mIndent = new Indent(); 130 } 131 132 /** 133 * Set flag that determines if XML DOCTYPE is written 134 * or not. Default is true. 135 * 136 */ 137 public void 138 setWriteDocType(boolean writeDocType) 139 { 140 mWriteDocType = writeDocType; 141 } 142 143 /** 144 * Write sequence into AGAVE XML format. 145 * @param seq maybe the or simple sequence 146 * <pre> 147 * if annotation of seq has chromosome information , generate <chromosome> tag 148 * if seq is SimpleAssembly, generate <contig> tag 149 * otherwise, generate <bio_sequence> tag 150 * currently each top-level sequence is wrapped into seperated sciobj xml file 151 * </pre> 152 */ 153 public void writeSequence(Sequence seq, PrintStream os) 154 throws IOException 155 { 156 mOut = new PrintWriter(os); 157 mFilter = new PCDATAFilterWriter(mOut); 158 159 mOut.println("<?xml version=\"1.0\"?>"); 160 if (mWriteDocType) 161 { 162 mOut.println("<!DOCTYPE sciobj SYSTEM \"agave.dtd\">"); 163 } 164 writeHeader(); 165 write(seq); 166 writeFooter(); 167 } 168 169 /** 170 * Write <sciobj> 171 * 172 */ 173 protected void 174 writeHeader() 175 { 176 mOut.println("<sciobj version=\"2\">"); 177 } 178 179 /** 180 * Write </sciobj> 181 */ 182 protected void 183 writeFooter() 184 { 185 mOut.println("</sciobj>"); 186 mOut.flush(); 187 } 188 189 /** 190 * 191 * Writing Sequence. 192 * @param seq is simple sequence or simple assembly 193 * 194 */ 195 protected void 196 write(Sequence seq) throws IOException 197 { 198 String chrom_num = mAnnotFilter.getChromNum( seq.getAnnotation() ); 199 if( chrom_num != null ) 200 { 201 mIndent.indent(); 202 mOut.print(mIndent); 203 mOut.println("<chromosome number=\"" + chrom_num + "\">"); 204 writeContig((Annotatable) seq ); 205 mOut.print(mIndent); 206 mOut.println("</chromosome>"); 207 mIndent.unIndent(); 208 } 209 else 210 { 211 if( seq instanceof SimpleAssembly) 212 { 213 writeContig( (Annotatable)seq ) ; 214 } 215 else 216 { 217 writeBioSequence((Annotatable)seq); 218 } 219 } 220 } 221 222 /** 223 * 224 * 225 */ 226 protected void 227 writeContig(Annotatable seq ) throws IOException 228 { 229 /** 230 <!ELEMENT contig (db_id , view? , note? , fragment_order* , unordered_fragments? , assembly? , 231 sequence? , sequence_map* , map_location* )> 232 <!ATTLIST contig length NMTOKEN #REQUIRED > 233 */ 234 mIndent.indent(); 235 mOut.print(mIndent); 236 mOut.print("<contig"); 237 238 239 mOut.print(" length=\""); 240 mOut.print( ((Sequence)seq).length() ); 241 mOut.print('"'); 242 mOut.println(">"); 243 244 writeDbId(seq); 245 writeNote(seq); 246 writeAssembly(seq); 247 writeDNA(seq) ; 248 writeMapLocation(seq) ; 249 250 251 mOut.print(mIndent); 252 mOut.println("</contig>"); 253 mIndent.unIndent(); 254 255 } 256 257 /** 258 * 259 * 260 */ 261 protected void 262 writeAssembly(Annotatable seq) throws IOException 263 { 264 /** <!ELEMENT assembly (bio_sequence | fragment_order)+ > */ 265 mIndent.indent(); 266 mOut.print(mIndent); 267 mOut.println("<assembly>"); 268 if(seq instanceof SimpleSequence) 269 write((Sequence) seq ) ; 270 else if( seq instanceof SimpleAssembly) 271 { 272 for (Iterator i =((Sequence) seq).features(); i.hasNext(); ) 273 { 274 Feature subf = (Feature)i.next(); 275 if( subf instanceof ComponentFeature) 276 writeBioSequence((Annotatable) ((ComponentFeature)subf).getComponentSequence() ) ; 277 } 278 } 279 280 mOut.print(mIndent); 281 mOut.println("</assembly>"); 282 mIndent.unIndent(); 283 } 284 285 /** 286 * 287 * 288 */ 289 protected void 290 writeBioSequence(Annotatable seq ) throws IOException 291 { 292 String s; 293 mIndent.indent(); 294 mOut.print(mIndent); 295 mOut.print("<bio_sequence"); 296 297 298 // write attributes 299 // 300 if( seq instanceof Sequence) 301 { 302 mOut.print(" seq_length=\""); 303 mOut.print( ((Sequence)seq).length() ); 304 mOut.print('"'); 305 } 306 307 s = mAnnotFilter.getOrganism(seq.getAnnotation()); 308 if (s != null) 309 { 310 mOut.print(" organism_name=\""); 311 mFilter.write(s); 312 mOut.print('"'); 313 } 314 315 s = mAnnotFilter.getMolType( seq.getAnnotation() ); 316 if (s == null && (seq instanceof Sequence)) { 317 s = ((Sequence) seq).getAlphabet().getName(); 318 } 319 if (s != null) 320 { 321 mOut.print(" molecule_type=\""); 322 mFilter.write(s); 323 mOut.print('"'); 324 } 325 326 s = mAnnotFilter.getElementId(seq.getAnnotation()); 327 if (s == null && (seq instanceof Sequence)) { 328 s = ((Sequence) seq).getName(); 329 } 330 if (s != null) 331 { 332 mOut.print(" element_id=\""); 333 mFilter.write(s); 334 mOut.print('"'); 335 } 336 337 s = mAnnotFilter.getSequenceId(seq.getAnnotation()); 338 if (s != null) 339 { 340 mOut.print(" sequence_id=\""); 341 mFilter.write(s); 342 mOut.print('"'); 343 } 344 345 s = mAnnotFilter.getTaxonId(seq.getAnnotation()); 346 if (s != null) 347 { 348 mOut.print(" taxon_id=\""); 349 mFilter.write(s); 350 mOut.print('"'); 351 } 352 353 s = mAnnotFilter.getCloneId(seq.getAnnotation()); 354 if (s != null) 355 { 356 mOut.print(" clone_id=\""); 357 mFilter.write(s); 358 mOut.print('"'); 359 } 360 361 s = mAnnotFilter.getCloneLibrary(seq.getAnnotation()); 362 if (s != null) 363 { 364 mOut.print(" clone_library=\""); 365 mFilter.write(s); 366 mOut.print('"'); 367 } 368 369 s = mAnnotFilter.getChromosome(seq.getAnnotation()); 370 if (s != null) 371 { 372 mOut.print(" chromosome=\""); 373 mFilter.write(s); 374 mOut.print('"'); 375 } 376 377 s = mAnnotFilter.getMapPosition(seq.getAnnotation()); 378 if (s != null) 379 { 380 mOut.print(" map_position=\""); 381 mFilter.write(s); 382 mOut.print('"'); 383 } 384 385 s = mAnnotFilter.getEcNumber(seq.getAnnotation()); 386 if (s != null) 387 { 388 mOut.print(" ec_number=\""); 389 mFilter.write(s); 390 mOut.print('"'); 391 } 392 393 s = mAnnotFilter.getCreateDate(seq.getAnnotation()); 394 if (s != null) 395 { 396 mOut.print(" update_date=\""); 397 mFilter.write(s); 398 mOut.print('"'); 399 } 400 401 402 mOut.println(">"); // close bio_sequence tag 403 404 // write content 405 writeDbId(seq) ; 406 writeDNA( seq ) ; 407 writeAltIds( seq ) ; 408 writeXrefs( seq ) ; 409 writeSequenceMap2(seq); // THOMASD hacked this.... 410 writeMapLocation(seq) ; 411 writeClassification(seq); 412 413 mIndent.unIndent(); 414 mOut.print(mIndent); 415 mOut.println("</bio_sequence>"); 416 } 417 418 /** 419 * group sequence_map by getSource() 420 */ 421 protected void 422 writeSequenceMap(Annotatable seq) throws IOException 423 { 424 for (Iterator i = ((FeatureHolder)seq).features(); i.hasNext();) 425 { 426 Feature f = (Feature) i.next(); 427 String type = f.getSource(); 428 if( type.equalsIgnoreCase("classification") ) 429 continue ; 430 // writeFeature( f ); 431 writeSequenceMap2( f ); 432 } 433 } 434 435 /** 436 * 437 * 438 */ 439 protected void 440 writeClassification(Annotatable seq) throws IOException 441 { 442 for (Iterator i = ((FeatureHolder)seq).features(); i.hasNext();) 443 { 444 Feature f = (Feature) i.next(); 445 String type = f.getSource(); 446 if( type.equalsIgnoreCase("classification") ) 447 { 448 writeClassification2(f) ; 449 } 450 } 451 } 452 453 /** 454 * 455 * 456 */ 457 private void 458 writeClassification2(Annotatable f) throws IOException 459 { 460 /** 461 <!ELEMENT classification (description? , id_alias* , evidence? )> 462 <!ATTLIST classification system CDATA #REQUIRED 463 id CDATA #REQUIRED 464 type CDATA #REQUIRED 465 assigned_by CDATA #IMPLIED > 466 */ 467 mOut.print(mIndent); 468 mOut.print("<classification"); 469 mIndent.indent(); 470 471 // write attributes 472 // 473 String s = mAnnotFilter.getClassifySystem( f.getAnnotation() ); ; 474 if(s != null) 475 { 476 mOut.print(" system=\""); 477 mFilter.write(s); 478 mOut.print('"'); 479 } 480 s = mAnnotFilter.getClassifyId( f.getAnnotation() ); ; 481 if(s != null) 482 { 483 mOut.print(" id=\""); 484 mFilter.write(s); 485 mOut.print('"'); 486 } 487 s = mAnnotFilter.getClassifyType( f.getAnnotation() ); ; 488 if(s != null) 489 { 490 mOut.print(" type=\""); 491 mFilter.write(s); 492 mOut.print('"'); 493 } 494 mOut.println(">"); // close map tag 495 496 writeDescription( f ) ; 497 writeIdAlias( f ) ; 498 writeEvidence( f ) ; 499 500 mOut.print(mIndent); 501 mOut.println("</classification>"); 502 mIndent.unIndent(); 503 } 504 505 /** 506 * 507 * 508 */ 509 private void 510 writeIdAlias(Annotatable f) throws IOException 511 { 512 AGAVEIdAlias[] annots = mAnnotFilter.getIdAlias(f.getAnnotation()); 513 if( annots != null ) 514 { 515 mIndent.indent(); 516 for(int i = 0 ; i < annots.length; i++) 517 mOut.print( annots[i].toString(mIndent.toString(), INDENT )); 518 mIndent.unIndent(); 519 } 520 } 521 522 /** 523 * Write SequenceMap XML 524 * 525 */ 526 protected void 527 writeSequenceMap2(Annotatable f) throws IOException 528 { 529/* 530<!ELEMENT sequence_map (note? , computation? , annotations? )> 531<!ATTLIST sequence_map label CDATA #IMPLIED > 532*/ 533 mIndent.indent(); 534 mOut.print(mIndent); 535 mOut.print("<sequence_map"); 536 537 538 // write attributes 539 // 540 String label = mAnnotFilter.getLabel(f.getAnnotation()) ; 541 if(label != null) 542 { 543 mOut.print(" label=\""); 544 mFilter.write(label); 545 mOut.print('"'); 546 } 547 mOut.println(">"); // close map tag 548 549 // write content 550 // 551 552 //write note 553 // 554 writeNote(f) ; 555 556 //ignore write computation 557 558 writeAnnotations((FeatureHolder) f); 559 560 mOut.print(mIndent); 561 mOut.println("</sequence_map>"); 562 mIndent.unIndent(); 563 564 } 565 566 /** 567 * 568 * 569 */ 570 protected void writeAnnotations(FeatureHolder f) throws IOException // changed to FeatureHolder THOMASD 571 { 572 //write annotation 573 // <!ELEMENT annotations (seq_feature | gene | comp_result )+ > 574 mIndent.indent(); 575 mOut.print(mIndent); 576 mOut.println("<annotations>"); 577 578 /* for (Iterator i = f.features(); i.hasNext(); ) 579 { 580 Feature feature = (Feature) i.next(); 581 if( feature.getSource().equalsIgnoreCase("annotations") ) 582 { 583 f = feature ; 584 break; 585 } 586 } */ 587 for (Iterator i = f.features(); i.hasNext(); ) 588 { 589 Feature feature = (Feature) i.next(); 590 String type = feature.getSource() ; 591 if( type == null || type.equalsIgnoreCase( "seq_feature" ) ) 592 writeSeqFeature(feature); 593 else if( type.equalsIgnoreCase( "gene") ) 594 writeGene( feature); 595 else { //default mapping to comp_result 596 // writeCompResult( feature); 597 writeSeqFeature(feature); // THOMASD 598 } 599 } 600 mOut.print(mIndent); 601 mOut.println("</annotations>"); 602 mIndent.unIndent(); 603 } 604 605 /** 606 * 607 * 608 */ 609 protected void 610 writeGene(Annotatable f) throws IOException 611 { 612 /** 613 <!ELEMENT gene (classification* , note? , seq_location , xrefs? , 614 evidence? , qualifier* , seq_feature* , related_annot* , 615 transcript*)> 616 <!ATTLIST gene element_id ID #IMPLIED 617 label CDATA #IMPLIED > 618 **/ 619 mIndent.indent(); 620 mOut.print(mIndent); 621 mOut.print("<gene"); 622 623 String s ; 624 625 s = mAnnotFilter.getElementId( f.getAnnotation() ); 626 if (s != null) 627 { 628 mOut.print(" element_id=\""); 629 mFilter.write(s); 630 mOut.print('"'); 631 } 632 633 s = mAnnotFilter.getLabel( f.getAnnotation() ); 634 if (s != null) 635 { 636 mOut.print(" label=\""); 637 mFilter.write(s); 638 mOut.print('"'); 639 } 640 641 642 mOut.println('>'); 643 644 // write content 645 writeNote(f) ; 646 writeSeqLocation( f ) ; 647 writeXrefs( f ) ; 648 writeEvidence(f) ; 649 writeProperty(f, AGAVEProperty.QUALIFIER ) ; 650 writeSubSeqFeature( f ) ; 651 writeRelatedAnnot( f ) ; 652 writeTranscript( f ) ; 653 654 655 mOut.print(mIndent); 656 mOut.println("</gene>"); 657 mIndent.unIndent(); 658 } 659 660 /** 661 * 662 * 663 */ 664 protected void 665 writeTranscript( Annotatable f) throws IOException 666 { 667 /** 668 * <!ELEMENT transcript (exons , cds? , mrna? , predicted_protein?)> 669 */ 670 for (Iterator i = ((FeatureHolder)f).features(); i.hasNext(); ) 671 { 672 Feature subf = (Feature)i.next(); 673 if( subf.getSource().equalsIgnoreCase("transcript") ) 674 writeTranscript2(subf); 675 } 676 } 677 678 /** 679 * 680 * 681 */ 682 private void 683 writeTranscript2(Annotatable f) throws IOException 684 { 685 mIndent.indent(); 686 mOut.print(mIndent); 687 mOut.println("<transcript>"); 688 writeExons(f); 689 for (Iterator i = ((FeatureHolder)f).features(); i.hasNext(); ) 690 { 691 Feature subf = (Feature)i.next(); 692 String type = subf.getSource() ; 693 if( type.equalsIgnoreCase("cds") ) 694 writeCds(subf); 695 else if( type.equalsIgnoreCase("mrna") ) 696 writeMrna(subf); 697 else if( type.equalsIgnoreCase("predicted_protein") ) 698 writePredictedProtein(subf); 699 700 } 701 mOut.print(mIndent); 702 mOut.println("</transcript>"); 703 mIndent.unIndent(); 704 } 705 706 /** 707 * 708 * 709 */ 710 private void 711 writeExons(Annotatable f) throws IOException 712 { 713 String[] ids = mAnnotFilter.getExonIds(f.getAnnotation()); 714 if( ids != null ) 715 { 716 mIndent.indent(); 717 mOut.print(mIndent); 718 mOut.println("<exons>"); 719 for(int i = 0 ; i < ids.length; i++) 720 { 721 mOut.println(mIndent + INDENT + "<element_id id=\"" + ids[i] + "\"/>"); 722 } 723 mOut.print(mIndent); 724 mOut.println("</exons>") ; 725 mIndent.unIndent(); 726 } 727 } 728 729 /** 730 * 731 * 732 */ 733 private void writeCds(Annotatable f) throws IOException 734 { 735 mIndent.indent(); 736 mOut.print(mIndent); 737 mOut.println("<cds>"); 738 writeBioSequence( f) ; 739 mOut.print(mIndent); 740 mOut.println("</cds>"); 741 mIndent.unIndent(); 742 } 743 744 /** 745 * 746 * 747 */ 748 private void writeMrna(Annotatable f) throws IOException 749 { 750 mIndent.indent(); 751 mOut.print(mIndent); 752 mOut.println("<mrna>"); 753 writeBioSequence( f) ; 754 mOut.print(mIndent); 755 mOut.println("</mrna>"); 756 mIndent.unIndent(); 757 } 758 759 /** 760 * 761 * 762 */ 763 private void writePredictedProtein(Annotatable f) throws IOException 764 { 765 mIndent.indent(); 766 mOut.print(mIndent); 767 mOut.println("<predicted_protein>"); 768 writeBioSequence( f) ; 769 mOut.print(mIndent); 770 mOut.println("</predicted_protein>"); 771 mIndent.unIndent(); 772 } 773 774 /** 775 * Write SeqFeature XML 776 */ 777 protected void 778 writeSeqFeature( Annotatable f) throws IOException 779 { 780/* 781<!ELEMENT seq_feature (classification* , note? , seq_location , xrefs? , 782 evidence? , qualifier* , seq_feature* , related_annot*)> 783<!ATTLIST seq_feature element_id ID #IMPLIED 784 feature_type CDATA #REQUIRED 785 label CDATA #IMPLIED > 786*/ 787 mIndent.indent(); 788 mOut.print(mIndent); 789 mOut.print("<seq_feature"); 790 791 792 // write attributes 793 // 794 String s = mAnnotFilter.getFeatureType( f.getAnnotation() ); 795 if (s == null) { // THOMASD 796 s = ((Feature) f).getType(); 797 } 798 mOut.print(" feature_type=\""); 799 mFilter.write( s == null? "default" : s ); 800 mOut.print('"'); 801 802 s = mAnnotFilter.getElementId( f.getAnnotation() ); 803 if (s != null) 804 { 805 mOut.print(" element_id=\""); 806 mFilter.write(s); 807 mOut.print('"'); 808 } 809 810 s = mAnnotFilter.getLabel( f.getAnnotation() ); 811 if (s != null) 812 { 813 mOut.print(" label=\""); 814 mFilter.write(s); 815 mOut.print('"'); 816 } 817 818 819 mOut.println('>'); 820 821 // write content 822 writeNote(f) ; 823 writeSeqLocation( f ) ; 824 writeXrefs( f ) ; 825 writeEvidence(f) ; 826 writeProperty(f, AGAVEProperty.QUALIFIER ) ; 827 writeSubSeqFeature( f ) ; 828 writeRelatedAnnot( f ) ; 829 830 831 mOut.print(mIndent); 832 mOut.println("</seq_feature>"); 833 mIndent.unIndent(); 834 835 } 836 837 /** 838 * 839 * 840 */ 841 private void 842 writeRelatedAnnot( Annotatable f) 843 { 844 AGAVERelatedAnnot[] annots = mAnnotFilter.getRelatedAnnot(f.getAnnotation()); 845 if( annots != null ) 846 { 847 for(int i = 0 ; i < annots.length; i++) 848 mOut.print( annots[i].toString(mIndent + INDENT, INDENT)); 849 } 850 } 851 852 /** 853 * 854 * 855 */ 856 private void 857 writeEvidence(Annotatable f) throws IOException 858 { 859 for (Iterator i = ((FeatureHolder)f).features(); i.hasNext(); ) 860 { 861 Feature subf = (Feature)i.next(); 862 if( subf.getSource().equalsIgnoreCase("evidence") ) 863 writeEvidence2(subf); 864 } 865 } 866 867 /** 868 * 869 * 870 */ 871 private void 872 writeEvidence2(Annotatable f) throws IOException 873 { 874 //element_ids 875 writeElementIds( f ) ; 876 //comp_result 877 for (Iterator i = ((FeatureHolder)f).features(); i.hasNext(); ) 878 { 879 Feature subf = (Feature)i.next(); 880 writeCompResult( subf ); 881 } 882 } 883 884 /** 885 * 886 * 887 */ 888 private void 889 writeElementIds(Annotatable f) throws IOException 890 { 891 String[] ids = mAnnotFilter.getElementIds(f.getAnnotation()); 892 if( ids != null ) 893 { 894 for(int i = 0 ; i < ids.length; i++) 895 { 896 mOut.println(mIndent + INDENT + "<element_id id=\"" + ids[i] + "\"/>"); 897 } 898 } 899 } 900 901 /* 902 <!ELEMENT comp_result (note? , match_desc? , match_align? , query_region? , 903 match_region? , result_property* , result_group* , 904 related_annot*)> 905 <!ATTLIST comp_result element_id ID #IMPLIED 906 result_id NMTOKEN #IMPLIED 907 group_order NMTOKEN #IMPLIED 908 result_type CDATA #REQUIRED 909 feature_type CDATA #IMPLIED 910 on_complement_strand (true | false ) 'false' 911 confidence NMTOKEN #IMPLIED 912 align_length NMTOKEN #IMPLIED 913 align_units (bp | AA) #IMPLIED > 914 */ 915 protected 916 void writeCompResult(Annotatable f) throws IOException 917 { 918 mIndent.indent(); 919 mOut.print(mIndent); 920 mOut.print("<comp_result"); 921 922 923 // write attributes 924 // 925 String s = mAnnotFilter.getResultType( f.getAnnotation() ); 926 mOut.print(" result_type=\""); 927 mFilter.write( s == null? "default" : s ); 928 mOut.print('"'); 929 930 s = mAnnotFilter.getElementId( f.getAnnotation() ); 931 if (s != null) 932 { 933 mOut.print(" element_id=\""); 934 mFilter.write(s); 935 mOut.print('"'); 936 } 937 938 String strand = "false"; 939 if( f instanceof StrandedFeature ) 940 { 941 char mark = ((StrandedFeature)f).getStrand().getToken() ; 942 if ( mark == '-' ) 943 strand= "true" ; 944 } 945 mOut.print(" on_complement_strand=\""); 946 mFilter.write(strand); 947 mOut.print('"'); 948 949 s = mAnnotFilter.getGroupOrder( f.getAnnotation() ); 950 if (s != null) 951 { 952 mOut.print(" group_order=\""); 953 mFilter.write(s); 954 mOut.print('"'); 955 } 956 957 s = mAnnotFilter.getFeatureType( f.getAnnotation() ); 958 if (s != null) 959 { 960 mOut.print(" feature_type=\""); 961 mFilter.write(s); 962 mOut.print('"'); 963 } 964 965 s = mAnnotFilter.getConfidence( f.getAnnotation() ); 966 if (s != null) 967 { 968 mOut.print(" confidence=\""); 969 mFilter.write(s); 970 mOut.print('"'); 971 } 972 973 s = mAnnotFilter.getAlignLength( f.getAnnotation() ); 974 if (s != null) 975 { 976 mOut.print(" align_length=\""); 977 mFilter.write(s); 978 mOut.print('"'); 979 } 980 s = mAnnotFilter.getAlignUnits( f.getAnnotation() ); 981 if (s != null) 982 { 983 mOut.print(" align_units=\""); 984 mFilter.write(s); 985 mOut.print('"'); 986 } 987 mOut.println(">"); 988 989 writeNote( f ) ; 990 writeMatchDesc( f ) ; 991 writeMatchAlign( f ) ; 992 writeQueryRegion( f ) ; 993 writeMatchRegion( f ) ; 994 writeProperty( f, AGAVEProperty.RESULT_PROPERTY) ; 995 writeResultGroup( f ) ; 996 writeRelatedAnnot(f); 997 998 mOut.print(mIndent); 999 mOut.println("</comp_result>"); 1000 mIndent.unIndent(); 1001 } 1002 1003 /** 1004 * <!ELEMENT result_group (comp_result+ )> 1005 * <!ATTLIST result_group group_order NMTOKEN '0' > 1006 */ 1007 private void 1008 writeResultGroup(Annotatable f) throws IOException 1009 { 1010 Iterator i = ((FeatureHolder)f).features() ; 1011 if( i == null ) //void 1012 return ; 1013 while( i.hasNext() ) 1014 { 1015 Feature subf = (Feature)i.next(); 1016 String type = subf.getSource(); 1017 if( type != null && type.equalsIgnoreCase("result_group") ) 1018 { 1019 mIndent.indent(); 1020 mOut.println( mIndent + "<result_group>"); 1021 for(Iterator k = subf.features(); k.hasNext();) 1022 writeCompResult( (Feature)k.next() ) ; 1023 mOut.println(mIndent + "</result_group>"); 1024 mIndent.unIndent(); 1025 } 1026 else 1027 { 1028 mIndent.indent(); 1029 mOut.println(mIndent + "<result_group>"); 1030 writeCompResult( subf ) ; 1031 mOut.println(mIndent + "</result_group>"); 1032 mIndent.unIndent(); 1033 } 1034 } 1035 } 1036 1037 /** 1038 * 1039 * 1040 */ 1041 private void 1042 writeQueryRegion(Annotatable f) throws IOException 1043 { 1044 AGAVEQueryRegion s = mAnnotFilter.getQueryRegion( f.getAnnotation() ); 1045 if( s != null ) 1046 { 1047 mIndent.indent(); 1048 mOut.println( s.toString(mIndent.toString() , INDENT ) ); 1049 mIndent.unIndent(); 1050 } 1051 } 1052 1053 /** 1054 * 1055 * 1056 */ 1057 private void 1058 writeMatchRegion(Annotatable f) throws IOException 1059 { 1060 AGAVEMatchRegion s = mAnnotFilter.getMatchRegion( f.getAnnotation() ); 1061 if( s != null ) 1062 { 1063 mIndent.indent(); 1064 mOut.println( s.toString(mIndent.toString() , INDENT ) ); 1065 mIndent.unIndent(); 1066 } 1067 } 1068 1069 /** 1070 * 1071 * 1072 */ 1073 private void 1074 writeMatchAlign(Annotatable f) throws IOException 1075 { 1076 String s = mAnnotFilter.getMatchAlign( f.getAnnotation() ); 1077 if( s != null ) 1078 { 1079 if (s.startsWith("<match_align") ) 1080 { 1081 mFilter.write(s); 1082 }else{ 1083 mIndent.indent(); 1084 mOut.print(mIndent); 1085 mOut.print("<match_align>"); 1086 mFilter.write(s); 1087 mOut.println("</match_align>"); 1088 mIndent.unIndent(); 1089 } 1090 } 1091 } 1092 1093 /** 1094 * 1095 * 1096 */ 1097 private void 1098 writeMatchDesc(Annotatable f) throws IOException 1099 { 1100 String s = mAnnotFilter.getMatchDesc( f.getAnnotation() ); 1101 if( s != null ) 1102 { 1103 if (s.startsWith("<match_desc") ) 1104 { 1105 mFilter.write(s); 1106 }else{ 1107 mIndent.indent(); 1108 mOut.print(mIndent); 1109 mOut.print("<match_desc>"); 1110 mFilter.write(s); 1111 mOut.println("</match_desc>"); 1112 mIndent.unIndent(); 1113 } 1114 } 1115 } 1116 1117 /** 1118 * 1119 * 1120 */ 1121 private void 1122 writeSubSeqFeature(Annotatable f ) throws IOException 1123 { 1124 for (Iterator i = ((FeatureHolder)f).features(); i.hasNext(); ) 1125 { 1126 Feature subf = (Feature)i.next(); 1127 //if the feature is not declared as <evidence> 1128 //treated as seq_feature 1129 if( subf.getSource().equalsIgnoreCase("evidence") ) 1130 continue ; 1131 if( subf.getSource().equalsIgnoreCase("transcript") ) 1132 continue ; 1133 writeSeqFeature( subf); 1134 } 1135 } 1136 1137 /** 1138 * 1139 * 1140 */ 1141 private void 1142 writeSeqLocation( Annotatable f) throws IOException 1143 { 1144 int min = ((Feature)f).getLocation().getMin(); 1145 int max = ((Feature)f).getLocation().getMax(); 1146 boolean on_complement_strand = false; 1147 if( f instanceof StrandedFeature) 1148 { 1149 int type = ((StrandedFeature)f).getStrand().getValue() ; 1150 if( type == 1 ) 1151 on_complement_strand = false ; 1152 else if( type == -1 ) 1153 on_complement_strand = true ; 1154 } 1155 mIndent.indent(); 1156 mOut.print(mIndent); 1157 mOut.print("<seq_location"); 1158 mOut.print(" least_start=\""); 1159 mOut.print(min); 1160 mOut.print('"'); 1161 1162 mOut.print(" greatest_end=\""); 1163 mOut.print(max); 1164 mOut.print('"'); 1165 1166 if( f instanceof StrandedFeature) 1167 { 1168 mOut.print(" on_complement_strand=\""); 1169 mOut.print(on_complement_strand ? "true" : "false"); 1170 mOut.print('"'); 1171 } 1172 mOut.print(">"); 1173 1174 mOut.print(min + ".." + max); 1175 mOut.println("</seq_location>"); 1176 mIndent.unIndent(); 1177 } 1178 1179 /** 1180 * 1181 * 1182 */ 1183 private void 1184 writeDNA(Annotatable seq) throws IOException 1185 { 1186 if( seq instanceof Sequence) 1187 { 1188 int i = ((Sequence)seq).length(); 1189 if (i > 0) 1190 { 1191 mIndent.indent(); 1192 mOut.print(mIndent); 1193 mOut.print("<sequence>"); 1194 int j ; 1195 for (j = 0 ; j < i / 80; j ++) 1196 { 1197 mOut.print(((Sequence)seq).subList(80 * j + 1, 80 * (j+1)).seqString() + "\n"); 1198 } 1199 1200 mOut.print(((Sequence)seq).subList(80 * j + 1, i ).seqString()); 1201 mOut.println("</sequence>"); 1202 mIndent.unIndent(); 1203 } 1204 } 1205 } 1206 1207 /** 1208 * 1209 * 1210 */ 1211 private void writeXrefs(Annotatable f) 1212 { 1213 AGAVEXrefs[] xrefs = mAnnotFilter.getXrefs(f.getAnnotation()); 1214 if( xrefs != null ) 1215 { 1216 mIndent.indent(); 1217 for(int i = 0 ; i < xrefs.length; i++) 1218 mOut.print( xrefs[i].toString(mIndent.toString(), INDENT)); 1219 mIndent.unIndent(); 1220 } 1221 } 1222 1223 /** 1224 * 1225 * 1226 */ 1227 private void 1228 writeAltIds(Annotatable f) throws IOException 1229 { 1230 AGAVEDbId[] db_id = mAnnotFilter.getAltIds(f.getAnnotation()); 1231 if( db_id!= null ) 1232 { 1233 mIndent.indent(); 1234 mOut.println(mIndent + "<alt_ids>"); 1235 mIndent.indent(); 1236 for(int i = 0 ; i < db_id.length; i++) 1237 mOut.print( db_id[i].toString(mIndent.toString(), INDENT)); 1238 mIndent.unIndent(); 1239 mOut.println(mIndent + "</alt_ids>"); 1240 mIndent.unIndent(); 1241 } 1242 } 1243 1244 /** 1245 * 1246 * 1247 */ 1248 private void 1249 writeProperty(Annotatable f, String type) 1250 { 1251 AGAVEProperty[] aps = mAnnotFilter.getProperty( f.getAnnotation(),type) ; 1252 if( aps != null ) 1253 { 1254 mIndent.indent(); 1255 for( int index = 0 ; index < aps.length; index++) 1256 mOut.print( aps[index].toString(mIndent.toString(), INDENT)); 1257 mIndent.unIndent(); 1258 } 1259 } 1260 1261 /** 1262 * 1263 * 1264 */ 1265 private void 1266 writeMapLocation(Annotatable f) throws IOException 1267 { 1268 AGAVEMapLocation[] mls = mAnnotFilter.getMapLocation(f.getAnnotation()); 1269 if( mls != null ) 1270 { 1271 mIndent.indent(); 1272 for(int i = 0 ; i < mls.length; i++) 1273 mOut.print( mls[i].toString(mIndent.toString(),INDENT)); 1274 mIndent.unIndent(); 1275 } 1276 } 1277 1278 /** 1279 * 1280 * 1281 */ 1282 private void 1283 writeDbId(Annotatable f) throws IOException 1284 { 1285 AGAVEDbId db_id = (AGAVEDbId)mAnnotFilter.getDbId(f.getAnnotation()); 1286 if( db_id!= null ) 1287 { 1288 mIndent.indent(); 1289 mOut.println( db_id.toString(mIndent.toString(), INDENT) ); 1290 mIndent.unIndent(); 1291 } 1292 } 1293 1294 /** 1295 * 1296 * 1297 */ 1298 private void 1299 writeDescription( Annotatable f) throws IOException 1300 { 1301 String s = mAnnotFilter.getDescription( f.getAnnotation() ); 1302 if( s != null ) 1303 { 1304 if (s.startsWith("<description") ) 1305 { 1306 mFilter.write(s); 1307 }else{ 1308 mIndent.indent(); 1309 mOut.print(mIndent); 1310 mOut.print("<description>"); 1311 mFilter.write(s); 1312 mOut.println("</description>"); 1313 mIndent.unIndent(); 1314 } 1315 } 1316 } 1317 1318 /** 1319 * 1320 * 1321 */ 1322 private void 1323 writeNote( Annotatable f) throws IOException 1324 { 1325 String note = mAnnotFilter.getNote(f.getAnnotation()); 1326 if( note!= null ) 1327 { 1328 if (note.startsWith("<note")) 1329 { 1330 mFilter.write(note); 1331 } 1332 else 1333 { 1334 mIndent.indent(); 1335 mOut.print(mIndent); 1336 mOut.print("<note>"); 1337 mFilter.write(note); 1338 mOut.println("</note>"); 1339 mIndent.unIndent(); 1340 } 1341 } 1342 } 1343} 1344