001 002 003 004package org.biojava.utils.automata; 005 006import java.util.Iterator; 007import java.util.LinkedList; 008import java.util.ListIterator; 009 010import org.biojava.bio.BioException; 011import org.biojava.bio.symbol.AlphabetIndex; 012import org.biojava.bio.symbol.AlphabetManager; 013import org.biojava.bio.symbol.FiniteAlphabet; 014import org.biojava.bio.symbol.IllegalAlphabetException; 015import org.biojava.bio.symbol.IllegalSymbolException; 016import org.biojava.bio.symbol.Symbol; 017import org.biojava.bio.symbol.SymbolList; 018 019public class PatternBlitz 020{ 021 FiniteAlphabet alfa; 022 023 private LinkedList patternStore; 024 private LinkedList instanceStore; 025 private PatternListener listener; 026 private StateMachineToolkit factory; 027 private AlphabetIndex alfaIdx; 028 029 public PatternBlitz(FiniteAlphabet alfa, StateMachineToolkit factory) 030 { 031 this.alfa = alfa; 032 alfaIdx = AlphabetManager.getAlphabetIndex(alfa); 033 patternStore = new LinkedList(); 034 instanceStore = new LinkedList(); 035 this.factory = factory; 036 } 037 038 public void lock() 039 { 040 041 } 042 043 public void setListener(PatternListener listener) 044 { 045 this.listener = listener; 046 } 047 048 /** 049 * add the specified regex to the patterns 050 * used for searching. 051 */ 052 public void addPattern(String pattern) 053 { 054 try { 055 // create DFA for pattern 056 FiniteAutomaton dfa = PatternMaker.compilePattern(pattern, alfa); 057 058 // convert to state machine 059 StateMachineFactory instanceFactory = factory.getFactory(pattern, dfa); 060 instanceFactory.setListener(listener); 061 062 // save in pattern store 063 patternStore.addLast(instanceFactory); 064 } 065 catch (BioException be) { 066 throw new AssertionError(be); 067 } 068 } 069 070 private void scanPatterns(Symbol sym, int start) 071 throws IllegalSymbolException 072 { 073 // convert symbol to its index 074 int symIdx = alfaIdx.indexForSymbol(sym); 075 076 // go thru' instance store with symbol index 077 for (ListIterator instanceI = instanceStore.listIterator(); 078 instanceI.hasNext(); ) { 079 080 // remove all terminal entries 081 StateMachineInstance instance = (StateMachineInstance) instanceI.next(); 082 if (!instance.transit(symIdx)) 083 instanceI.remove(); 084 } 085 086 // now traverse the pattern store to initiate new instances 087 for (Iterator patternI = patternStore.iterator(); 088 patternI.hasNext(); ) { 089 090 StateMachineFactory factory = (StateMachineFactory) patternI.next(); 091 092 StateMachineInstance newInstance; 093 if ((newInstance = factory.startInstance(symIdx, start)) != null) { 094 instanceStore.addLast(newInstance); 095 } 096 } 097 } 098 099 public void search(SymbolList sl) 100 throws IllegalAlphabetException 101 { 102 // check compatible alphabets 103 if (sl.getAlphabet() != alfa) 104 throw new IllegalAlphabetException("incompatible alphabets"); 105 106 try { 107 for (int i=1; i < sl.length(); i++) { 108 Symbol sym = sl.symbolAt(i); 109 110 scanPatterns(sym, i); 111 } 112 } 113 catch (IllegalSymbolException ise) { 114 throw new AssertionError(ise); 115 } 116 } 117 118} 119