001package org.biojava.bio.program.tagvalue; 002 003import org.biojava.utils.ParserException; 004 005/** 006 * Joins multipel values into single values. 007 * 008 * <p> 009 * Some properties have values spread across multiple lines. For example, 010 * the properties on EMBL features can be spread across multiple lines.</p> 011 * 012 * <p> 013 * This class provides callbacks to allow event streams to be re-written 014 * so that they contain this information. 015 * </p> 016 * 017 * @since 1.4 018 * @author Matthew Pocock 019 */ 020public class Aggregator extends SimpleTagValueWrapper { 021 private BoundaryFinder observer; 022 private String joiner; 023 024 // state 025 // 026 private StringBuffer value; 027 private boolean inValue; 028 029 public Aggregator(TagValueListener listener, BoundaryFinder observer, String joiner) { 030 super(listener); 031 this.observer = observer; 032 this.joiner = joiner; 033 this.value = new StringBuffer(); 034 } 035 036 public BoundaryFinder getBoundaryFinder() { 037 return observer; 038 } 039 040 public void setBoundaryFinder(BoundaryFinder finder) { 041 this.observer = finder; 042 } 043 044 public String getJoiner() { 045 return joiner; 046 } 047 048 public void setJoiner(String joiner) { 049 this.joiner = joiner; 050 } 051 052 public void startTag(Object tag) 053 throws ParserException { 054 super.startTag(tag); 055 inValue = false; 056 value.setLength(0); 057 } 058 059 public void value(TagValueContext ctxt, Object value) 060 throws ParserException { 061 boolean isStart = observer.isBoundaryStart(value); 062 boolean isEnd = observer.isBoundaryEnd(value); 063 boolean dbv = observer.dropBoundaryValues(); 064 065 if(isStart && isEnd) { 066 if(inValue) { 067 super.value(ctxt, this.value.toString()); 068 this.value.setLength(0); 069 inValue = false; 070 } 071 072 if(!dbv) { 073 super.value(ctxt, value); 074 } 075 } 076 077 if(isStart && !isEnd) { 078 if(inValue) { 079 super.value(ctxt, this.value.toString()); 080 this.value.setLength(0); 081 } 082 this.value.append(value); 083 inValue = true; 084 } 085 086 if(!isStart && isEnd) { 087 if(!dbv) { 088 this.value.append(joiner); 089 this.value.append(value); 090 } 091 092 super.value(ctxt, this.value.toString()); 093 inValue = false; 094 this.value.setLength(0); 095 } 096 097 if(!isStart && !isEnd) { 098 this.value.append(joiner); 099 this.value.append(value); 100 inValue = true; 101 } 102 } 103 104 public void endTag() 105 throws ParserException { 106 if(inValue) { 107 super.value(null, this.value.toString()); 108 inValue = false; 109 } 110 super.endTag(); 111 } 112}