edu.rice.cs.drjava.model
Class FindReplaceMachine

java.lang.Object
  extended by edu.rice.cs.drjava.model.FindReplaceMachine

public class FindReplaceMachine
extends Object

Implementation of logic of find/replace over a document.

Version:
$Id: FindReplaceMachine.java 5354 2010-08-10 22:41:14Z mgricken $

Field Summary
private  int _current
           
private  OpenDefinitionsDocument _doc
           
private  DocumentIterator _docIterator
           
private  String _findWord
           
private  OpenDefinitionsDocument _firstDoc
           
private  Component _frame
           
private  boolean _ignoreCommentsAndStrings
           
private  boolean _ignoreTestCases
           
private  boolean _isForward
           
private  String _lastFindWord
           
private static Log _log
           
private  boolean _matchCase
           
private  boolean _matchWholeWord
           
private  SingleDisplayModel _model
           
private  String _replaceWord
           
private  boolean _searchAllDocuments
           
private  boolean _searchSelectionOnly
           
private  MovingDocumentRegion _selectionRegion
           
private  boolean _skipText
           
 
Constructor Summary
FindReplaceMachine(SingleDisplayModel model, DocumentIterator docIterator, Component frame)
          Standard Constructor.
 
Method Summary
private  FindResult _findNextInDoc(OpenDefinitionsDocument doc, int start, int len, boolean searchAll)
          Finds next match in specified doc only.
private  FindResult _findNextInDocSegment(OpenDefinitionsDocument doc, int start, int len)
          Find first valid match withing specified segment of doc.
private  FindResult _findNextInDocSegment(OpenDefinitionsDocument doc, int start, int len, boolean wrapped, boolean allWrapped)
          Main helper method for findNext...
private  FindResult _findNextInOtherDocs(OpenDefinitionsDocument startDoc, int start, int len)
          Searches all documents following startDoc for _findWord, cycling through the documents in the direction specified by _isForward.
private  FindResult _findWrapped(OpenDefinitionsDocument doc, int start, int len, boolean allWrapped)
          Helper method for findNext that looks for a match after searching has wrapped off the "end" (start if searching backward) of the document.
private  int _processAllInCurrentDoc(Runnable1<FindResult> findAction, boolean searchSelectionOnly)
          Processes all occurences of _findWord in _doc.
private  int _replaceAllInCurrentDoc(boolean searchSelectionOnly)
          Replaces all occurences of _findWord with _replaceWord in _doc.
private  boolean _shouldIgnore(int foundOffset, OpenDefinitionsDocument odd)
          Returns true if the currently found instance should be ignored (either because it is inside a string or comment or because it does not match the whole word when either or both of those conditions are set to true).
 void cleanUp()
           
 FindResult findNext()
           
private  FindResult findNext(boolean searchAll)
          Finds the next occurrence of the find word and returns an offset at the end of that occurrence or -1 if the word was not found.
 int getCurrentOffset()
          Gets the character offset to which this machine is currently pointing.
 OpenDefinitionsDocument getDocument()
           
 String getFindWord()
           
 OpenDefinitionsDocument getFirstDoc()
           
 boolean getIgnoreCommentsAndStrings()
           
 boolean getIgnoreTestCases()
           
 boolean getMatchCase()
           
 boolean getMatchWholeWord()
           
 String getReplaceWord()
           
 boolean getSearchAllDocuments()
           
 boolean getSearchSelectionOnly()
           
private  boolean isDelimiter(char ch)
          Determines whether a character is a delimiter (not a letter or digit) as a helper to wholeWordFoundAtCurrent
 boolean isSearchBackwards()
           
 boolean onMatch()
          Determine if the machine is on an instance of the find word.
 void positionChanged()
          Called when the current position is updated in the document implying _skipText should not be set if the user toggles _searchBackwards
private  int processAll(Runnable1<FindResult> findAction, boolean searchAll, boolean searchSelectionOnly)
          Processes all occurences of the find word with the replace word in the current document or in all documents depending the value of the flag searchAll.
 int processAll(Runnable1<FindResult> findAction, MovingDocumentRegion region)
          Processes all occurences of the find word with the replace word in the current document or in all documents depending the value of the machine register _searchAllDocuments.
 int replaceAll()
          Replaces all occurrences of the find word with the replace word in the current document of in all documents depending the value of the machine register _searchAllDocuments.
private  int replaceAll(boolean searchAll, boolean searchSelectionOnly)
          Replaces all occurences of the find word with the replace word in the current document of in all documents or in the current selection of the current document depending the value of the flag searchAll
 boolean replaceCurrent()
          If we're on a match for the find word, replace it with the replace word.
 void setDocument(OpenDefinitionsDocument doc)
           
 void setFindAnyOccurrence()
           
 void setFindWord(String word)
          Change the word being sought.
 void setFirstDoc(OpenDefinitionsDocument firstDoc)
           
 void setIgnoreCommentsAndStrings(boolean ignoreCommentsAndStrings)
           
 void setIgnoreTestCases(boolean ignoreTestCases)
           
 void setLastFindWord()
           
 void setMatchCase(boolean matchCase)
           
 void setMatchWholeWord()
           
 void setPosition(int pos)
           
 void setReplaceWord(String word)
          Change the replacing word.
 void setSearchAllDocuments(boolean searchAllDocuments)
           
 void setSearchBackwards(boolean searchBackwards)
           
 void setSearchSelectionOnly(boolean searchSelectionOnly)
           
 void setSelection(MovingDocumentRegion s)
          Set the selected text region.
private  boolean wholeWordFoundAtCurrent(OpenDefinitionsDocument doc, int foundOffset)
          Determines whether the whole find word is found at the input position.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

_log

private static Log _log

_doc

private OpenDefinitionsDocument _doc

_firstDoc

private OpenDefinitionsDocument _firstDoc

_current

private int _current

_selectionRegion

private MovingDocumentRegion _selectionRegion

_findWord

private String _findWord

_replaceWord

private String _replaceWord

_matchCase

private boolean _matchCase

_matchWholeWord

private boolean _matchWholeWord

_searchAllDocuments

private boolean _searchAllDocuments

_searchSelectionOnly

private boolean _searchSelectionOnly

_isForward

private boolean _isForward

_ignoreCommentsAndStrings

private boolean _ignoreCommentsAndStrings

_ignoreTestCases

private boolean _ignoreTestCases

_lastFindWord

private String _lastFindWord

_skipText

private boolean _skipText

_docIterator

private DocumentIterator _docIterator

_model

private SingleDisplayModel _model

_frame

private Component _frame
Constructor Detail

FindReplaceMachine

public FindReplaceMachine(SingleDisplayModel model,
                          DocumentIterator docIterator,
                          Component frame)
Standard Constructor. Creates new machine to perform find/replace operations on a particular document starting from a given position.

Parameters:
docIterator - an object that allows navigation through open Swing documents (it is DefaultGlobalModel)
Method Detail

cleanUp

public void cleanUp()

positionChanged

public void positionChanged()
Called when the current position is updated in the document implying _skipText should not be set if the user toggles _searchBackwards


setLastFindWord

public void setLastFindWord()

isSearchBackwards

public boolean isSearchBackwards()

setSearchBackwards

public void setSearchBackwards(boolean searchBackwards)

setMatchCase

public void setMatchCase(boolean matchCase)

getMatchCase

public boolean getMatchCase()

setMatchWholeWord

public void setMatchWholeWord()

getMatchWholeWord

public boolean getMatchWholeWord()

setFindAnyOccurrence

public void setFindAnyOccurrence()

setSearchAllDocuments

public void setSearchAllDocuments(boolean searchAllDocuments)

setSearchSelectionOnly

public void setSearchSelectionOnly(boolean searchSelectionOnly)

setIgnoreCommentsAndStrings

public void setIgnoreCommentsAndStrings(boolean ignoreCommentsAndStrings)

getIgnoreCommentsAndStrings

public boolean getIgnoreCommentsAndStrings()

setIgnoreTestCases

public void setIgnoreTestCases(boolean ignoreTestCases)

getIgnoreTestCases

public boolean getIgnoreTestCases()

setDocument

public void setDocument(OpenDefinitionsDocument doc)

setFirstDoc

public void setFirstDoc(OpenDefinitionsDocument firstDoc)

setPosition

public void setPosition(int pos)

getCurrentOffset

public int getCurrentOffset()
Gets the character offset to which this machine is currently pointing.


getFindWord

public String getFindWord()

getReplaceWord

public String getReplaceWord()

getSearchAllDocuments

public boolean getSearchAllDocuments()

getSearchSelectionOnly

public boolean getSearchSelectionOnly()

getDocument

public OpenDefinitionsDocument getDocument()

getFirstDoc

public OpenDefinitionsDocument getFirstDoc()

setFindWord

public void setFindWord(String word)
Change the word being sought.

Parameters:
word - the new word to seek

setReplaceWord

public void setReplaceWord(String word)
Change the replacing word.

Parameters:
word - the new replacing word

onMatch

public boolean onMatch()
Determine if the machine is on an instance of the find word. Only executes in event thread except for initialization.

Returns:
true if the current position is right after an instance of the find word.

replaceCurrent

public boolean replaceCurrent()
If we're on a match for the find word, replace it with the replace word. Only executes in event thread.


setSelection

public void setSelection(MovingDocumentRegion s)
Set the selected text region.

Parameters:
s - selected region

replaceAll

public int replaceAll()
Replaces all occurrences of the find word with the replace word in the current document of in all documents depending the value of the machine register _searchAllDocuments.

Returns:
the number of replacements

replaceAll

private int replaceAll(boolean searchAll,
                       boolean searchSelectionOnly)
Replaces all occurences of the find word with the replace word in the current document of in all documents or in the current selection of the current document depending the value of the flag searchAll

Returns:
the number of replacements

_replaceAllInCurrentDoc

private int _replaceAllInCurrentDoc(boolean searchSelectionOnly)
Replaces all occurences of _findWord with _replaceWord in _doc. Never searches in other documents. Starts at the beginning or the end of the document (depending on find direction). This convention ensures that matches created by string replacement will not be replaced as in the following example:

findString: "hello"
replaceString: "e"
document text: "hhellollo"

Depending on the cursor position, clicking replace all could either make the document text read "hello" (which is correct) or "e". This is because of the behavior of findNext(), and it would be incorrect to change that behavior. Only executes in event thread.

Returns:
the number of replacements

processAll

public int processAll(Runnable1<FindResult> findAction,
                      MovingDocumentRegion region)
Processes all occurences of the find word with the replace word in the current document or in all documents depending the value of the machine register _searchAllDocuments.

Parameters:
findAction - action to perform on the occurrences; input is the FindResult, output is ignored
Returns:
the number of processed occurrences

processAll

private int processAll(Runnable1<FindResult> findAction,
                       boolean searchAll,
                       boolean searchSelectionOnly)
Processes all occurences of the find word with the replace word in the current document or in all documents depending the value of the flag searchAll. Assumes that findAction does not modify the document it processes. Only executes in event thread.

Parameters:
findAction - action to perform on the occurrences; input is the FindResult, output is ignored
Returns:
the number of replacements

_processAllInCurrentDoc

private int _processAllInCurrentDoc(Runnable1<FindResult> findAction,
                                    boolean searchSelectionOnly)
Processes all occurences of _findWord in _doc. Never processes other documents. Starts at the beginning or the end of the document (depending on find direction). This convention ensures that matches created by string replacement will not be replaced as in the following example:

findString: "hello"
replaceString: "e"
document text: "hhellollo"

Assumes this has mutually exclusive access to _doc (e.g., by hourglassOn) and findAction does not modify _doc. Only executes in event thread.

Parameters:
findAction - action to perform on the occurrences; input is the FindResult, output is ignored
Returns:
the number of replacements

findNext

public FindResult findNext()

findNext

private FindResult findNext(boolean searchAll)
Finds the next occurrence of the find word and returns an offset at the end of that occurrence or -1 if the word was not found. In a forward search, the match offset is the RIGHT edge of the word. In subsequent searches, the same instance won't be found again. In a backward search, the position returned is the LEFT edge of the word. Also returns a flag indicating whether the end of the document was reached and wrapped around. This is done using the FindResult class which contains the matching document, an integer offset and two flag indicated whether the search wrapped (within _doc and across all documents). Only executes in the event thread.

Parameters:
searchAll - whether to search all documents (or just _doc)
Returns:
a FindResult object containing foundOffset and a flag indicating wrapping to the beginning during a search

_findNextInDoc

private FindResult _findNextInDoc(OpenDefinitionsDocument doc,
                                  int start,
                                  int len,
                                  boolean searchAll)
Finds next match in specified doc only. If searching forward, len must be doc.getLength(). If searching backward, start must be 0. If searchAll, suppress executing in-document wrapped search, because it must be deferred. Only runs in the event thread. Note than this method does a wrapped search if specified search fails.


_findWrapped

private FindResult _findWrapped(OpenDefinitionsDocument doc,
                                int start,
                                int len,
                                boolean allWrapped)
Helper method for findNext that looks for a match after searching has wrapped off the "end" (start if searching backward) of the document. Only runs in event thread. INVARIANT (! _isForward => start = 0) && (_isForward => start + len = doc.getLength()).

Parameters:
doc - the document in which search wrapped
start - the location of preceding text segment where search FAILED.
len - the length of text segment previously searched
allWrapped - whether this wrapped search is being performed after an all document search has wrapped
Returns:
the offset where the instance was found. Returns -1 if no instance was found between start and end

_findNextInDocSegment

private FindResult _findNextInDocSegment(OpenDefinitionsDocument doc,
                                         int start,
                                         int len)
Find first valid match withing specified segment of doc.


_findNextInDocSegment

private FindResult _findNextInDocSegment(OpenDefinitionsDocument doc,
                                         int start,
                                         int len,
                                         boolean wrapped,
                                         boolean allWrapped)
Main helper method for findNext... that searches for _findWord inside the specified document segment. Only runs in the event thread.

Parameters:
doc - document to be searched
start - the location (offset/left edge) of the text segment to be searched
len - the requested length of the text segment to be searched
wrapped - whether this search is after wrapping around the document
allWrapped - whether this seach is after wrapping around all documents
Returns:
a FindResult object with foundOffset and a flag indicating wrapping to the beginning during a search. The foundOffset returned insided the FindResult is -1 if no instance was found.

_findNextInOtherDocs

private FindResult _findNextInOtherDocs(OpenDefinitionsDocument startDoc,
                                        int start,
                                        int len)
Searches all documents following startDoc for _findWord, cycling through the documents in the direction specified by _isForward. If the search cycles back to doc without finding a match, performs a wrapped search on doc.

Parameters:
startDoc - document where searching started and just failed
start - location in startDoc of the document segment where search failed.
len - length of the text segment where search failed.
Returns:
the FindResult containing the information for where we found _findWord or a dummy FindResult.

wholeWordFoundAtCurrent

private boolean wholeWordFoundAtCurrent(OpenDefinitionsDocument doc,
                                        int foundOffset)
Determines whether the whole find word is found at the input position. Assumes read lock or hourglass is already held.

Parameters:
doc - - the document where an instance of the find word was found
foundOffset - - the position where that instance was found
Returns:
true if the whole word is found at foundOffset, false otherwise

isDelimiter

private boolean isDelimiter(char ch)
Determines whether a character is a delimiter (not a letter or digit) as a helper to wholeWordFoundAtCurrent

Parameters:
ch - - a character
Returns:
true if ch is a delimiter, false otherwise

_shouldIgnore

private boolean _shouldIgnore(int foundOffset,
                              OpenDefinitionsDocument odd)
Returns true if the currently found instance should be ignored (either because it is inside a string or comment or because it does not match the whole word when either or both of those conditions are set to true). Only executes in event thread.

Parameters:
foundOffset - the location of the instance found
odd - the current document where the instance was found
Returns:
true if the location should be ignored, false otherwise