/* * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7) * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle * * This file is part of Jalview. * * Jalview is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with Jalview. If not, see . */ package jalview.analysis; import java.util.*; import jalview.datamodel.*; public class Finder { /** * Implements the search algorithms for the Find dialog box. */ SearchResults searchResults; AlignmentI alignment; jalview.datamodel.SequenceGroup selection = null; Vector idMatch = null; boolean caseSensitive = false; boolean findAll = false; com.stevesoft.pat.Regex regex = null; /** * hold's last-searched position between calles to find(false) */ int seqIndex = 0, resIndex = -1; public Finder(AlignmentI alignment, SequenceGroup selection) { this.alignment = alignment; this.selection = selection; } /** * restart search at given sequence and residue on alignment and (optionally) * contained in selection * * @param alignment * @param selectionGroup * @param seqIndex * @param resIndex */ public Finder(AlignmentI alignment, SequenceGroup selectionGroup, int seqIndex, int resIndex) { this(alignment, selectionGroup); this.seqIndex = seqIndex; this.resIndex = resIndex; } public boolean find(String searchString) { boolean hasResults = false; if (!caseSensitive) { searchString = searchString.toUpperCase(); } regex = new com.stevesoft.pat.Regex(searchString); regex.setIgnoreCase(!caseSensitive); searchResults = new SearchResults(); idMatch = new Vector(); Sequence seq; String item = null; boolean found = false; int end = alignment.getHeight(); // ///////////////////////////////////////////// if (selection != null) { if ((selection.getSize() < 1) || ((selection.getEndRes() - selection.getStartRes()) < 2)) { selection = null; } } while (!found && (seqIndex < end)) { seq = (Sequence) alignment.getSequenceAt(seqIndex); if ((selection != null && selection.getSize() > 0) && !selection.getSequences(null).contains(seq)) { seqIndex++; resIndex = -1; continue; } if (resIndex < 0) { resIndex = 0; // test for one off matches - sequence position and sequence ID // //// is the searchString a residue number? try { int res = Integer.parseInt(searchString); // possibly a residue number - check if valid for seq if (seq.getEnd() >= res) { searchResults.addResult(seq, res, res); hasResults = true; //resIndex=seq.getLength(); // seqIndex++; if (!findAll) { found = true; break; } } } catch (NumberFormatException ex) { } if (regex.search(seq.getName())) { idMatch.addElement(seq); hasResults = true; if (!findAll) { // stop and return the match found = true; break; } } } item = seq.getSequenceAsString(); if ((selection != null) && (selection.getEndRes() < alignment.getWidth() - 1)) { item = item.substring(0, selection.getEndRes() + 1); } // /Shall we ignore gaps???? - JBPNote: Add Flag for forcing this or not StringBuffer noGapsSB = new StringBuffer(); int insertCount = 0; Vector spaces = new Vector(); for (int j = 0; j < item.length(); j++) { if (!jalview.util.Comparison.isGap(item.charAt(j))) { noGapsSB.append(item.charAt(j)); spaces.addElement(new Integer(insertCount)); } else { insertCount++; } } String noGaps = noGapsSB.toString(); for (int r = resIndex; r < noGaps.length(); r++) { if (regex.searchFrom(noGaps, r)) { resIndex = regex.matchedFrom(); if ((selection != null && selection.getSize() > 0) && ((resIndex + Integer.parseInt(spaces.elementAt( resIndex).toString())) < selection.getStartRes())) { continue; } int sres = seq .findPosition(resIndex + Integer.parseInt(spaces.elementAt(resIndex) .toString())); int eres = seq.findPosition(regex.matchedTo() - 1 + Integer.parseInt(spaces .elementAt(regex.matchedTo() - 1).toString())); searchResults.addResult(seq, sres, eres); hasResults = true; if (!findAll) { // thats enough, break and display the result found = true; resIndex++; break; } r = resIndex; } else { break; } } if (!found) { seqIndex++; resIndex = -1; } } /** * We now search the Id string in the main search loop. for (int id = 0; id * < alignment.getHeight(); id++) { if * (regex.search(alignment.getSequenceAt(id).getName())) { * idMatch.addElement(alignment.getSequenceAt(id)); hasResults = true; } } */ return hasResults; } /** * @return the alignment */ public AlignmentI getAlignment() { return alignment; } /** * @param alignment * the alignment to set */ public void setAlignment(AlignmentI alignment) { this.alignment = alignment; } /** * @return the caseSensitive */ public boolean isCaseSensitive() { return caseSensitive; } /** * @param caseSensitive * the caseSensitive to set */ public void setCaseSensitive(boolean caseSensitive) { this.caseSensitive = caseSensitive; } /** * @return the findAll */ public boolean isFindAll() { return findAll; } /** * @param findAll * the findAll to set */ public void setFindAll(boolean findAll) { this.findAll = findAll; } /** * @return the selection */ public jalview.datamodel.SequenceGroup getSelection() { return selection; } /** * @param selection * the selection to set */ public void setSelection(jalview.datamodel.SequenceGroup selection) { this.selection = selection; } /** * @return the idMatch */ public Vector getIdMatch() { return idMatch; } /** * @return the regex */ public com.stevesoft.pat.Regex getRegex() { return regex; } /** * @return the searchResults */ public SearchResults getSearchResults() { return searchResults; } /** * @return the resIndex */ public int getResIndex() { return resIndex; } /** * @param resIndex * the resIndex to set */ public void setResIndex(int resIndex) { this.resIndex = resIndex; } /** * @return the seqIndex */ public int getSeqIndex() { return seqIndex; } /** * @param seqIndex * the seqIndex to set */ public void setSeqIndex(int seqIndex) { this.seqIndex = seqIndex; } }