refactored search algorithm from gui classes
[jalview.git] / src / jalview / analysis / Finder.java
1 package jalview.analysis;
2 import java.util.Vector;
3
4 import jalview.datamodel.*;
5
6 public class Finder {
7     /**
8      * Implements the search algorithms for the Find dialog box.
9      */
10     SearchResults searchResults;
11     AlignmentI alignment;
12     jalview.datamodel.SequenceGroup selection=null;
13     Vector idMatch=null;
14     boolean caseSensitive=false;
15     boolean findAll=false;
16     com.stevesoft.pat.Regex regex=null;
17     public Finder(AlignmentI alignment, SequenceGroup selection) {
18         this.alignment=alignment;
19         this.selection = selection;
20     }
21     public boolean find(String searchString) {
22         boolean hasResults=false;
23         if(!caseSensitive)
24             searchString = searchString.toUpperCase();
25         regex = new com.stevesoft.pat.Regex(searchString);
26         searchResults = new SearchResults();
27         idMatch = new Vector();
28         Sequence seq;
29         int seqIndex=0,resIndex=0;
30         String item = null;
31         boolean found = false;
32
33         ////// is the searchString a residue number?
34         try
35         {
36             int res = Integer.parseInt(searchString);
37             found = true;
38             if (selection == null || selection.getSize(false) < 1)
39             {
40               seq = (Sequence) alignment.getSequenceAt(0);
41             }
42             else
43             {
44               seq = (Sequence) (selection.getSequenceAt(0));
45             }
46
47             searchResults.addResult(seq, res, res);
48             hasResults=true;
49         }
50         catch (NumberFormatException ex)
51         {
52         }
53
54         ///////////////////////////////////////////////
55
56         int end = alignment.getHeight();
57
58         
59         if (selection != null)
60         {
61             if ((selection.getSize(false) < 1) ||
62                     ((selection.getEndRes() - selection.getStartRes()) < 2))
63             {
64                 selection = null;
65             }
66         }
67
68         while (!found && (seqIndex < end))
69         {
70             seq = (Sequence) alignment.getSequenceAt(seqIndex);
71
72             if ((selection != null) && !selection.getSequences(false).contains(seq))
73             {
74                 seqIndex++;
75                 resIndex = 0;
76
77                 continue;
78             }
79
80             item = seq.getSequenceAsString();
81             // JBPNote - check if this toUpper which is present in the application implementation makes a difference
82             //if(!caseSensitive)
83             //  item = item.toUpperCase();
84
85             if ((selection != null) &&
86                     (selection.getEndRes() < alignment.getWidth()-1))
87             {
88                 item = item.substring(0, selection.getEndRes() + 1);
89             }
90             
91             ///Shall we ignore gaps???? - JBPNote: Add Flag for forcing this or not
92             StringBuffer noGapsSB = new StringBuffer();
93             int insertCount = 0;
94             Vector spaces = new Vector();
95
96             for (int j = 0; j < item.length(); j++)
97             {
98                 if (!jalview.util.Comparison.isGap(item.charAt(j)))
99                 {
100                     noGapsSB.append(item.charAt(j));
101                     spaces.add(new Integer(insertCount));
102                 }
103                 else
104                 {
105                     insertCount++;
106                 }
107             }
108
109             String noGaps = noGapsSB.toString();
110
111             for (int r = resIndex; r < noGaps.length(); r++)
112             {
113
114                 if (regex.searchFrom(noGaps, r))
115                 {
116                     resIndex = regex.matchedFrom();
117
118                     if ((selection != null) &&
119                             ((resIndex +
120                             Integer.parseInt(spaces.get(resIndex).toString())) < selection.getStartRes()))
121                     {
122                         continue;
123                     }
124
125
126                     int sres = seq.findPosition(resIndex +
127                             Integer.parseInt(spaces.elementAt(resIndex)
128                                                    .toString()));
129                     int eres = seq.findPosition(regex.matchedTo() - 1 +
130                             Integer.parseInt(spaces.elementAt(regex.matchedTo() -
131                                     1).toString()));
132
133                     searchResults.addResult(seq, sres, eres);
134                     hasResults=true;
135                     if (!findAll)
136                     {
137                         // thats enough, break and display the result
138                         found = true;
139                         resIndex++;
140
141                         break;
142                     }
143
144                     r = resIndex;
145                 }
146                 else
147                 {
148                   break;
149                 }
150             }
151
152             if (!found)
153             {
154                 seqIndex++;
155                 resIndex = 0;
156             }
157         }
158
159         for (int id = 0; id < alignment.getHeight(); id++)
160         {
161             if (regex.search(alignment.getSequenceAt(id).getName()))
162             {
163                 idMatch.add(alignment.getSequenceAt(id));
164                 hasResults=true;
165             }
166         }
167         return hasResults;
168     }
169     /**
170      * @return the alignment
171      */
172     public AlignmentI getAlignment() {
173         return alignment;
174     }
175     /**
176      * @param alignment the alignment to set
177      */
178     public void setAlignment(AlignmentI alignment) {
179         this.alignment = alignment;
180     }
181     /**
182      * @return the caseSensitive
183      */
184     public boolean isCaseSensitive() {
185         return caseSensitive;
186     }
187     /**
188      * @param caseSensitive the caseSensitive to set
189      */
190     public void setCaseSensitive(boolean caseSensitive) {
191         this.caseSensitive = caseSensitive;
192     }
193     /**
194      * @return the findAll
195      */
196     public boolean isFindAll() {
197         return findAll;
198     }
199     /**
200      * @param findAll the findAll to set
201      */
202     public void setFindAll(boolean findAll) {
203         this.findAll = findAll;
204     }
205     /**
206      * @return the selection
207      */
208     public jalview.datamodel.SequenceGroup getSelection() {
209         return selection;
210     }
211     /**
212      * @param selection the selection to set
213      */
214     public void setSelection(jalview.datamodel.SequenceGroup selection) {
215         this.selection = selection;
216     }
217     /**
218      * @return the idMatch
219      */
220     public Vector getIdMatch() {
221         return idMatch;
222     }
223     /**
224      * @return the regex
225      */
226     public com.stevesoft.pat.Regex getRegex() {
227         return regex;
228     }
229     /**
230      * @return the searchResults
231      */
232     public SearchResults getSearchResults() {
233         return searchResults;
234     }
235 }