/* Copyright (C) 2003-2011 JabRef contributors.
This program 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 2 of the License, or
(at your option) any later version.
This program 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, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package net.sf.jabref;
import java.util.*;
public class EntrySorter implements DatabaseChangeListener {
//TreeSet set;
final ArrayList<BibtexEntry> set;
Comparator<BibtexEntry> comp;
String[] idArray;
BibtexEntry[] entryArray;
//static BibtexEntry[] DUMMY = new BibtexEntry[0];
private boolean outdated = false;
private boolean changed = false;
public EntrySorter(Map<String, BibtexEntry> entries, Comparator<BibtexEntry> comp) {
//set = new TreeSet(comp);
set = new ArrayList<BibtexEntry>();
this.comp = comp;
Set<String> keySet = entries.keySet();
if (keySet != null) {
Iterator<String> i = keySet.iterator();
while (i.hasNext()) {
set.add(entries.get(i.next()));
}
//Collections.sort(set, comp);
changed = true;
index();
}
}
public void index() {
/* Old version, from when set was a TreeSet.
// The boolean "changing" is true in the situation that an entry is about to change,
// and has temporarily been removed from the entry set in this sorter. So, if we index
// now, we will cause exceptions other places because one entry has been left out of
// the indexed array. Simply waiting foth this to change can lead to deadlocks,
// so we have no other choice than to return without indexing.
if (changing)
return;
*/
synchronized(set) {
// Resort if necessary:
if (changed) {
Collections.sort(set, comp);
changed = false;
}
// Create an array of IDs for quick access, since getIdAt() is called by
// getValueAt() in EntryTableModel, which *has* to be efficient.
int count = set.size();
idArray = new String[count];
entryArray = new BibtexEntry[count];
int piv = 0;
for (Iterator<BibtexEntry> i=set.iterator(); i.hasNext();) {
// for (int i=0; i<idArray.length; i++) {
BibtexEntry entry = i.next();
idArray[piv] = entry.getId();
entryArray[piv] = entry;
piv++;
}
}
}
public boolean isOutdated() {
return outdated;
}
public String getIdAt(int pos) {
synchronized(set) {
return idArray[pos];
}
//return ((BibtexEntry)(entryArray[pos])).getId();
}
public BibtexEntry getEntryAt(int pos) {
synchronized(set) {
return entryArray[pos];
}
}
public int getEntryCount() {
synchronized(set) {
if (entryArray != null)
return entryArray.length;
else
return 0;
}
}
public void databaseChanged(DatabaseChangeEvent e) {
synchronized(set) {
int pos;
switch (e.getType()) {
case ADDED_ENTRY:
pos = -Collections.binarySearch(set, e.getEntry(), comp) - 1;
set.add(pos, e.getEntry());
//addEntry(e.getEntry());
//set.add(e.getEntry());
//changed = true;
//Collections.sort(set, comp);
break;
case REMOVED_ENTRY:
set.remove(e.getEntry());
changed = true;
break;
case CHANGED_ENTRY:
// Entry changed. Resort list:
//Collections.sort(set, comp);
pos = Collections.binarySearch(set, e.getEntry(), comp);
int posOld = set.indexOf(e.getEntry());
if (pos < 0) {
set.remove(posOld);
set.add(-pos-1, e.getEntry());
}
//changed = true;
break;
}
}
}
}