/* Copyright (C) 2003 Morten O. Alver All programs in this directory and subdirectories are published under the GNU General Public License as described below. 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Further information about the GNU GPL is available at: http://www.gnu.org/copyleft/gpl.ja.html */ 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) { if (e.getType() == DatabaseChangeEvent.ADDED_ENTRY) { int 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); } else if (e.getType() == DatabaseChangeEvent.REMOVED_ENTRY) { set.remove(e.getEntry()); changed = true; } else if (e.getType() == DatabaseChangeEvent.CHANGED_ENTRY) { // Entry changed. Resort list: //Collections.sort(set, comp); int 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; } } } }