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