/* Wotonomy: OpenStep design patterns for pure Java applications. Copyright (C) 2000 Michael Powers This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see http://www.gnu.org */ package net.wotonomy.datastore; import java.util.Comparator; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.TreeMap; /** * This implementation of DataIndex wraps a TreeMap and adds the ability to * contain objects with duplicate keys. */ public class DefaultDataIndex implements DataIndex { static final long serialVersionUID = -3759982714240822885L; protected String name; protected String property; private TreeMap treeMap; private Comparator comparator; public DefaultDataIndex() { comparator = new DefaultComparator(); setTreeMap(new TreeMap(new DefaultComparator())); } public DefaultDataIndex(String aName, String aProperty) { this(); setName(aName); setProperty(aProperty); } // included for xml serialization public Comparator getComparator() { return comparator; } public void setComparator(Comparator aComparator) { comparator = aComparator; // set comparator and copy contents TreeMap map = getTreeMap(); setTreeMap(new TreeMap(comparator)); getTreeMap().putAll(map); } public String getName() { return name; }; public void setName(String aName) { name = aName; } public String getProperty() { return property; }; public void setProperty(String aProperty) { property = aProperty; } public TreeMap getTreeMap() { return treeMap; } public void setTreeMap(TreeMap aMap) { treeMap = aMap; } public List query(Object beginValue, Object endValue) { //System.out.println( "DefaultDataIndex.query: " + beginValue + " : " + endValue ); List result = new LinkedList(); if (endValue == null) { if (beginValue == null) { // begin and end are null, return entire set populateListFromIterator(result, treeMap.values().iterator()); return result; } // only end is null, return all starting from beginValue populateListFromIterator(result, treeMap.tailMap(beginValue).values().iterator()); return result; } else if (beginValue == null) { // only begin is null, return all ending with endValue populateListFromIterator(result, treeMap.headMap(endValue).values().iterator()); } else { // begin and end are specified, return all inclusive populateListFromIterator(result, treeMap.subMap(beginValue, endValue).values().iterator()); } // append endValue results, so it's inclusive Object o = treeMap.get(endValue); if (o != null) { if (o instanceof DuplicateList) { populateListFromIterator(result, ((DuplicateList) o).iterator()); } else { result.add(o); } } // return complete result return result; } protected void populateListFromIterator(List aList, Iterator it) { Object o; while (it.hasNext()) { o = it.next(); if (o instanceof DuplicateList) { populateListFromIterator(aList, ((DuplicateList) o).iterator()); } else { aList.add(o); } } } public Object addObject(Object anObject, Object newValue) { Object o = treeMap.get(newValue); if (o != null) { if (o instanceof DuplicateList) { ((DuplicateList) o).add(anObject); return anObject; } DuplicateList list = new DuplicateList(); list.add(o); list.add(anObject); anObject = list; } if (anObject == null) new RuntimeException().printStackTrace(); treeMap.put(newValue, anObject); return anObject; } public Object updateObject(Object anObject, Object oldValue, Object newValue) { removeObject(anObject, oldValue); return addObject(anObject, newValue); } public Object removeObject(Object anObject, Object oldValue) { Object o = treeMap.get(oldValue); if (o != null) { if (o instanceof DuplicateList) { // remove this item from the list DuplicateList list = (DuplicateList) o; list.remove(anObject); // if there are still duplicates, return if (list.size() > 1) return anObject; // else, list size must be one if (list.size() == 0) { System.out.println("DefaultDataIndex.deleteObject: " + oldValue + " : list size is 1 : this should never happen."); return null; } // replace existing list with remaining item from list treeMap.remove(oldValue); treeMap.put(oldValue, list.getFirst()); return anObject; } // otherwise, proceed normally treeMap.remove(oldValue); } return anObject; } public void clear() { treeMap.clear(); } public String toString() { return "DefaultDataIndex: " + name + " : " + property + " : " + treeMap.toString(); } } /* * $Log$ Revision 1.2 2006/02/19 16:26:19 cgruber Move non-unit-test code to * tests project Fix up code to work with proper imports Fix maven dependencies. * * Revision 1.1 2006/02/16 13:18:56 cgruber Check in all sources in * eclipse-friendly maven-enabled packages. * * Revision 1.2 2003/08/14 19:29:38 chochos minor cleanup (imports, static * method calls, etc) * * Revision 1.1.1.1 2000/12/21 15:47:11 mpowers Contributing wotonomy. * * Revision 1.3 2000/12/20 16:25:36 michael Added log to all files. * * */