/**************************************************************************
OmegaT - Computer Assisted Translation (CAT) tool
with fuzzy matching, translation memory, keyword search,
glossaries, and translation leveraging into updated projects.
Copyright (C) 2009 Alex Buloichik
Home page: http://www.omegat.org/
Support center: http://groups.yahoo.com/group/OmegaT/
This file is part of OmegaT.
OmegaT 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.
OmegaT 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 this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/
package org.omegat.gui.common;
import javax.swing.SwingUtilities;
import org.omegat.core.data.SourceTextEntry;
import org.omegat.util.Log;
/**
* Base class for search info about current entry in the separate thread.
*
* Implementation must check isEntryChanged method and exit if antry changed,
* against create multimple threads when user travels by entries fast.
*
* @author Alex Buloichik (alex73mail@gmail.com)
*
* @param <T>
* result type of found data
*/
public abstract class EntryInfoSearchThread<T> extends Thread {
private final EntryInfoThreadPane<T> pane;
/**
* Entry which processed currently.
*
* If entry in pane was changed, it means user was moved to other entry, and
* there is no sense to continue search.
*/
protected final SourceTextEntry currentlyProcessedEntry;
/**
* Constructor.
*
* @param pane
* entry info pane
* @param entry
* current entry
*/
public EntryInfoSearchThread(final EntryInfoThreadPane<T> pane, final SourceTextEntry entry) {
this.pane = pane;
this.currentlyProcessedEntry = entry;
}
/**
* Check if current entry was changed. If user moved to other entry, there
* is no sence to continue search.
*
* @return true if current entry was changed
*/
protected boolean isEntryChanged() {
return currentlyProcessedEntry != pane.currentlyProcessedEntry;
}
/**
* Throws exception if entry changed for stop processing.
*/
protected void checkEntryChanged() throws EntryChangedException {
if (isEntryChanged()) {
throw new EntryChangedException();
}
}
@Override
public void run() {
if (isEntryChanged()) {
return;
}
T result = null;
Exception error = null;
try {
result = search();
} catch (EntryChangedException ex) {
// entry changed - there is no sence to display results
return;
} catch (Exception ex) {
error = ex;
Log.log(ex);
}
if (isEntryChanged()) {
return;
}
final T fresult = result;
final Exception ferror = error;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (isEntryChanged()) {
return;
}
if (ferror != null) {
pane.setError(ferror);
} else {
pane.setFoundResult(currentlyProcessedEntry, fresult);
}
}
});
}
/**
* Implementation-dependent method for search info.
*
* If entry changed, method can return null.
*
* @return result of search
*/
protected abstract T search() throws EntryChangedException, Exception;
/**
* Any search can generate this exception for stop searching if entry changed. All callers must catch it
* and just skip.
*/
@SuppressWarnings("serial")
public static class EntryChangedException extends RuntimeException {
}
}