2 Copyright (C) 2003 Nizar N. Batada, Morten O. Alver
4 All programs in this directory and
5 subdirectories are published under the GNU General Public License as
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 Further information about the GNU GPL is available at:
24 http://www.gnu.org/copyleft/gpl.ja.html
30 // modified : r.nagel 2.09.2004
31 // - new SearcherThread.setFinish() method
32 // - replace thread.sleep in run() by wait() and notify() mechanism
34 package net.sf.jabref;
36 import net.sf.jabref.undo.NamedCompound;
37 import net.sf.jabref.undo.UndoableRemoveEntry;
38 import java.util.Vector;
40 public class DuplicateSearch extends Thread {
44 final Vector duplicates = new Vector();
46 public DuplicateSearch(BasePanel bp) {
51 NamedCompound ce = null;
52 int duplicateCounter = 0;
53 panel.output(Globals.lang("Searching for duplicates..."));
54 Object[] keys = panel.database.getKeySet().toArray();
55 if ((keys == null) || (keys.length < 2))
57 bes = new BibtexEntry[keys.length];
58 for (int i=0; i<keys.length; i++)
59 bes[i] = panel.database.getEntryById((String)keys[i]);
61 SearcherThread st = new SearcherThread();
62 st.setPriority(Thread.MIN_PRIORITY);
65 DuplicateResolverDialog drd = null;
68 loop: while (!st.finished() || (current < duplicates.size()))
70 if ( current >= duplicates.size() )
72 // No more duplicates to resolve, but search is still in progress. Sleep a little.
76 } catch (InterruptedException ex) {}
82 while (!st.finished() || (current < duplicates.size()))
84 if (current >= duplicates.size() )
86 // wait until the search thread puts something into duplicates vector
88 synchronized(duplicates)
94 catch (Exception e) {}
96 } else // duplicates found
98 BibtexEntry[] be = ( BibtexEntry[] ) duplicates.get( current ) ;
100 if ( ( panel.database.getEntryById( be[0].getId() ) != null ) &&
101 ( panel.database.getEntryById( be[1].getId() ) != null ) )
104 drd = new DuplicateResolverDialog( panel.frame, be[0], be[1],
105 DuplicateResolverDialog.DUPLICATE_SEARCH) ;
106 drd.setVisible(true); // drd.show(); -> deprecated since 1.5
109 int answer = drd.getSelected() ;
110 if ( answer == DuplicateResolverDialog.KEEP_UPPER )
112 if ( ce == null ) ce = new NamedCompound(Globals.lang("duplicate removal")) ;
113 panel.database.removeEntry( be[1].getId() ) ;
114 panel.markBaseChanged() ;
115 ce.addEdit( new UndoableRemoveEntry( panel.database, be[1], panel ) ) ;
117 else if ( answer == DuplicateResolverDialog.KEEP_LOWER )
119 if ( ce == null ) ce = new NamedCompound(Globals.lang("duplicate removal")) ;
120 panel.database.removeEntry( be[0].getId() ) ;
121 panel.markBaseChanged() ;
122 ce.addEdit( new UndoableRemoveEntry( panel.database, be[0], panel ) ) ;
124 else if ( answer == DuplicateResolverDialog.BREAK )
126 st.setFinished() ; // thread killing
127 current = Integer.MAX_VALUE ;
128 duplicateCounter-- ; // correct counter
138 panel.output(Globals.lang("Duplicate pairs found") + ": " + duplicates.size()
139 +" " +Globals.lang("pairs processed") +": " +duplicateCounter );
145 panel.undoManager.addEdit(ce);
152 class SearcherThread extends Thread {
154 private boolean finished = false;
157 for (int i = 0; (i < bes.length - 1) && !finished ; i++) {
158 for (int j = i + 1; (j < bes.length) && !finished ; j++) {
159 boolean eq = Util.isDuplicate(bes[i], bes[j],
160 Globals.duplicateThreshold);
162 // If (suspected) duplicates, add them to the duplicates vector.
165 synchronized (duplicates)
167 duplicates.add( new BibtexEntry[] {bes[i], bes[j]} ) ;
168 duplicates.notifyAll(); // send wake up all
175 // if no duplicates found, the graphical thread will never wake up
176 synchronized(duplicates)
178 duplicates.notifyAll();
182 public boolean finished() {
186 // Thread cancel option
187 // no synchronized used because no "realy" critical situations expected
188 public void setFinished()