| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||||||
| DefaultDataIndex | 
 | 
 | 2.176470588235294;2.176 | 
| 1 |  /* | |
| 2 |  Wotonomy: OpenStep design patterns for pure Java applications. | |
| 3 |  Copyright (C) 2000 Michael Powers | |
| 4 | ||
| 5 |  This library is free software; you can redistribute it and/or | |
| 6 |  modify it under the terms of the GNU Lesser General Public | |
| 7 |  License as published by the Free Software Foundation; either | |
| 8 |  version 2.1 of the License, or (at your option) any later version. | |
| 9 | ||
| 10 |  This library is distributed in the hope that it will be useful, | |
| 11 |  but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 |  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | |
| 13 |  Lesser General Public License for more details. | |
| 14 | ||
| 15 |  You should have received a copy of the GNU Lesser General Public | |
| 16 |  License along with this library; if not, see http://www.gnu.org | |
| 17 |  */ | |
| 18 | ||
| 19 |  package net.wotonomy.datastore; | |
| 20 | ||
| 21 |  import java.util.Comparator; | |
| 22 |  import java.util.Iterator; | |
| 23 |  import java.util.LinkedList; | |
| 24 |  import java.util.List; | |
| 25 |  import java.util.TreeMap; | |
| 26 | ||
| 27 |  /** | |
| 28 |  * This implementation of DataIndex wraps a TreeMap and | |
| 29 |  * adds the ability to contain objects with duplicate keys. | |
| 30 |  */ | |
| 31 | public class DefaultDataIndex implements DataIndex | |
| 32 |  { | |
| 33 | static final long serialVersionUID = -3759982714240822885L; | |
| 34 | ||
| 35 |      protected String name; | |
| 36 |      protected String property; | |
| 37 |      private TreeMap treeMap;     | |
| 38 |      private Comparator comparator; | |
| 39 | ||
| 40 | 0 |      public DefaultDataIndex() | 
| 41 | 0 |      { | 
| 42 | 0 |          comparator = new DefaultComparator(); | 
| 43 | 0 |          setTreeMap( new TreeMap( new DefaultComparator() ) ); | 
| 44 | 0 |      } | 
| 45 | ||
| 46 |      public DefaultDataIndex( String aName, String aProperty ) | |
| 47 |      { | |
| 48 | 0 |          this(); | 
| 49 | 0 |              setName( aName ); | 
| 50 | 0 |                  setProperty( aProperty ); | 
| 51 | 0 |      } | 
| 52 | ||
| 53 |      // included for xml serialization     | |
| 54 | 0 |      public Comparator getComparator() { return comparator; } | 
| 55 | public void setComparator( Comparator aComparator ) | |
| 56 |      {  | |
| 57 | 0 |          comparator = aComparator;  | 
| 58 |          // set comparator and copy contents | |
| 59 | 0 |          TreeMap map = getTreeMap(); | 
| 60 | 0 |          setTreeMap( new TreeMap( comparator ) ); | 
| 61 | 0 |          getTreeMap().putAll( map ); | 
| 62 | ||
| 63 | 0 |      } | 
| 64 | ||
| 65 | 0 |      public String getName() { return name; }; | 
| 66 | 0 |      public void setName( String aName ) { name = aName; } | 
| 67 | 0 |      public String getProperty() { return property; }; | 
| 68 | 0 |      public void setProperty( String aProperty ) { property = aProperty; } | 
| 69 | 0 |      public TreeMap getTreeMap() { return treeMap; } | 
| 70 | 0 |      public void setTreeMap( TreeMap aMap ) { treeMap = aMap; } | 
| 71 | ||
| 72 |      public List query( Object beginValue, Object endValue ) | |
| 73 |      { | |
| 74 |  //System.out.println( "DefaultDataIndex.query: " + beginValue + " : " + endValue ); | |
| 75 | 0 |                  List result = new LinkedList(); | 
| 76 | 0 |              if ( endValue == null ) | 
| 77 |              { | |
| 78 | 0 |                      if ( beginValue == null ) | 
| 79 |                      { | |
| 80 |                              // begin and end are null, return entire set | |
| 81 | 0 |                              populateListFromIterator( result, treeMap.values().iterator() ); | 
| 82 | 0 |                              return result; | 
| 83 | } | |
| 84 | ||
| 85 |                      // only end is null, return all starting from beginValue | |
| 86 | 0 |                      populateListFromIterator( result, | 
| 87 | 0 |                              treeMap.tailMap( beginValue ).values().iterator() ); | 
| 88 | 0 |                          return result; | 
| 89 | } | |
| 90 |              else | |
| 91 | 0 |              if ( beginValue == null ) | 
| 92 |              { | |
| 93 |                      // only begin is null, return all ending with endValue | |
| 94 | 0 |              populateListFromIterator( result, | 
| 95 | 0 |                  treeMap.headMap( endValue ).values().iterator() ); | 
| 96 | 0 |              } | 
| 97 |              else | |
| 98 |              { | |
| 99 |                      // begin and end are specified, return all inclusive | |
| 100 | 0 |              populateListFromIterator( result, | 
| 101 | 0 |                  treeMap.subMap( beginValue, endValue ).values().iterator() ); | 
| 102 | } | |
| 103 | ||
| 104 |                  // append endValue results, so it's inclusive | |
| 105 | 0 |              Object o = treeMap.get( endValue ); | 
| 106 | 0 |              if ( o != null ) | 
| 107 |              { | |
| 108 | 0 |              if ( o instanceof DuplicateList ) | 
| 109 |              { | |
| 110 | 0 |                  populateListFromIterator( result, | 
| 111 | 0 |                      ((DuplicateList)o).iterator() ); | 
| 112 | 0 |              } | 
| 113 |              else | |
| 114 |              { | |
| 115 | 0 |                  result.add( o ); | 
| 116 | } | |
| 117 | } | |
| 118 | ||
| 119 |                  // return complete result | |
| 120 | 0 |                  return result; | 
| 121 | } | |
| 122 | ||
| 123 | protected void populateListFromIterator( List aList, Iterator it ) | |
| 124 |      { | |
| 125 | Object o; | |
| 126 | 0 |              while ( it.hasNext() ) | 
| 127 |              { | |
| 128 | 0 |                      o = it.next(); | 
| 129 | 0 |                      if ( o instanceof DuplicateList ) | 
| 130 |                      { | |
| 131 | 0 |                              populateListFromIterator(  | 
| 132 | 0 |                                      aList, ((DuplicateList)o).iterator() ); | 
| 133 | 0 |                      } | 
| 134 |                      else | |
| 135 |                      { | |
| 136 | 0 |                              aList.add( o ); | 
| 137 | } | |
| 138 | 0 |              } | 
| 139 | 0 |      } | 
| 140 | ||
| 141 |      public Object addObject( Object anObject, Object newValue ) | |
| 142 |      { | |
| 143 | 0 |              Object o = treeMap.get( newValue ); | 
| 144 | 0 |          if ( o != null ) | 
| 145 |          { | |
| 146 | 0 |              if ( o instanceof DuplicateList ) | 
| 147 |              { | |
| 148 | 0 |                  ((DuplicateList)o).add( anObject ); | 
| 149 | 0 |                  return anObject; | 
| 150 | } | |
| 151 | ||
| 152 | 0 |              DuplicateList list = new DuplicateList(); | 
| 153 | 0 |              list.add( o ); | 
| 154 | 0 |              list.add( anObject ); | 
| 155 | 0 |              anObject = list; | 
| 156 | ||
| 157 | } | |
| 158 | 0 |  if ( anObject == null ) new RuntimeException().printStackTrace(); | 
| 159 | ||
| 160 | 0 |              treeMap.put( newValue, anObject ); | 
| 161 | 0 |              return anObject; | 
| 162 | } | |
| 163 | ||
| 164 |      public Object updateObject( Object anObject,  | |
| 165 | Object oldValue, Object newValue ) | |
| 166 |      { | |
| 167 | 0 |              removeObject( anObject, oldValue ); | 
| 168 | 0 |                  return addObject( anObject, newValue ); | 
| 169 | } | |
| 170 | ||
| 171 |      public Object removeObject( Object anObject, Object oldValue ) | |
| 172 |      { | |
| 173 | 0 |              Object o = treeMap.get( oldValue ); | 
| 174 | 0 |          if ( o != null ) | 
| 175 |          { | |
| 176 | 0 |              if ( o instanceof DuplicateList ) | 
| 177 |              { | |
| 178 |                  // remove this item from the list | |
| 179 | 0 |                  DuplicateList list = (DuplicateList) o; | 
| 180 | 0 |                  list.remove( anObject ); | 
| 181 | ||
| 182 |                                  // if there are still duplicates, return | |
| 183 | 0 |                  if ( list.size() > 1 ) | 
| 184 | 0 |                      return anObject; | 
| 185 | ||
| 186 |                  // else, list size must be one | |
| 187 | 0 |                  if ( list.size() == 0 ) | 
| 188 |                  { | |
| 189 | 0 |                      System.out.println( "DefaultDataIndex.deleteObject: " + oldValue | 
| 190 | 0 |                          + " : list size is 1 : this should never happen." ); | 
| 191 | 0 |                                          return null; | 
| 192 | } | |
| 193 | ||
| 194 |                  // replace existing list with remaining item from list | |
| 195 | 0 |                  treeMap.remove( oldValue ); | 
| 196 | 0 |                      treeMap.put( oldValue, list.getFirst() ); | 
| 197 | 0 |                      return anObject; | 
| 198 | } | |
| 199 | ||
| 200 |                          // otherwise, proceed normally | |
| 201 | 0 |              treeMap.remove( oldValue ); | 
| 202 | } | |
| 203 | 0 |                  return anObject; | 
| 204 | } | |
| 205 | ||
| 206 | public void clear() | |
| 207 |      { | |
| 208 | 0 |              treeMap.clear(); | 
| 209 | 0 |      }     | 
| 210 | ||
| 211 |      public String toString()  | |
| 212 |      { | |
| 213 | 0 |         return "DefaultDataIndex: " + name + " : " + property + " : " + treeMap.toString(); | 
| 214 | } | |
| 215 | ||
| 216 | } | |
| 217 | ||
| 218 |  /* | |
| 219 |   * $Log$ | |
| 220 |   * Revision 1.2  2006/02/19 16:26:19  cgruber | |
| 221 |   * Move non-unit-test code to tests project | |
| 222 |   * Fix up code to work with proper imports | |
| 223 |   * Fix maven dependencies. | |
| 224 |   * | |
| 225 |   * Revision 1.1  2006/02/16 13:18:56  cgruber | |
| 226 |   * Check in all sources in eclipse-friendly maven-enabled packages. | |
| 227 |   * | |
| 228 |   * Revision 1.2  2003/08/14 19:29:38  chochos | |
| 229 |   * minor cleanup (imports, static method calls, etc) | |
| 230 |   * | |
| 231 |   * Revision 1.1.1.1  2000/12/21 15:47:11  mpowers | |
| 232 |   * Contributing wotonomy. | |
| 233 |   * | |
| 234 |   * Revision 1.3  2000/12/20 16:25:36  michael | |
| 235 |   * Added log to all files. | |
| 236 |   * | |
| 237 |   * | |
| 238 |   */ | |
| 239 |