1 56 package org.objectstyle.cayenne.access.util; 57 58 import java.util.ArrayList ; 59 import java.util.HashMap ; 60 import java.util.HashSet ; 61 import java.util.Iterator ; 62 import java.util.List ; 63 import java.util.Map ; 64 import java.util.Set ; 65 66 import org.objectstyle.cayenne.CayenneException; 67 import org.objectstyle.cayenne.access.ResultIterator; 68 import org.objectstyle.cayenne.map.DbAttribute; 69 import org.objectstyle.cayenne.map.DbEntity; 70 71 82 public class DistinctResultIterator implements ResultIterator { 83 84 protected ResultIterator wrappedIterator; 85 protected Set fetchedIds; 86 protected Map nextDataRow; 87 protected DbEntity defaultEntity; 88 protected boolean readingIds; 89 90 96 public DistinctResultIterator(ResultIterator wrappedIterator, DbEntity defaultEntity) 97 throws CayenneException { 98 if (wrappedIterator == null) { 99 throw new CayenneException("Null wrapped iterator."); 100 } 101 102 if (defaultEntity == null) { 103 throw new CayenneException("Null defaultEntity."); 104 } 105 106 this.wrappedIterator = wrappedIterator; 107 this.defaultEntity = defaultEntity; 108 this.fetchedIds = new HashSet (); 109 110 checkNextRow(); 111 } 112 113 116 public void close() throws CayenneException { 117 wrappedIterator.close(); 118 } 119 120 123 public List dataRows(boolean close) throws CayenneException { 124 List list = new ArrayList (); 125 126 try { 127 while (this.hasNextRow()) { 128 list.add(this.nextDataRow()); 129 } 130 return list; 131 } 132 finally { 133 if (close) { 134 this.close(); 135 } 136 } 137 } 138 139 public int getDataRowWidth() { 140 return wrappedIterator.getDataRowWidth(); 141 } 142 143 public boolean hasNextRow() throws CayenneException { 144 return nextDataRow != null; 145 } 146 147 public Map nextDataRow() throws CayenneException { 148 if (!hasNextRow()) { 149 throw new CayenneException( 150 "An attempt to read uninitialized row or past the end of the iterator."); 151 } 152 153 Map row = nextDataRow; 154 checkNextRow(); 155 return row; 156 } 157 158 162 public Map nextObjectId(DbEntity entity) throws CayenneException { 163 if (!hasNextRow()) { 164 throw new CayenneException( 165 "An attempt to read uninitialized row or past the end of the iterator."); 166 } 167 168 Map row = nextDataRow; 169 170 if (!readingIds) { 172 Iterator it = row.entrySet().iterator(); 173 while (it.hasNext()) { 174 Map.Entry entry = (Map.Entry ) it.next(); 175 String name = (String ) entry.getKey(); 176 DbAttribute attribute = (DbAttribute) entity.getAttribute(name); 177 if (attribute == null || !attribute.isPrimaryKey()) { 178 it.remove(); 179 } 180 } 181 } 182 183 checkNextId(entity); 184 return row; 185 } 186 187 public void skipDataRow() throws CayenneException { 188 if (!hasNextRow()) { 189 throw new CayenneException( 190 "An attempt to read uninitialized row or past the end of the iterator."); 191 } 192 193 if (readingIds) { 194 checkNextId(defaultEntity); 195 } 196 else { 197 checkNextRow(); 198 } 199 } 200 201 void checkNextRow() throws CayenneException { 202 if (readingIds) { 203 throw new CayenneException( 204 "Can't go back from reading ObjectIds to reading rows."); 205 } 206 207 nextDataRow = null; 208 while (wrappedIterator.hasNextRow()) { 209 Map next = wrappedIterator.nextDataRow(); 210 211 215 Map id = new HashMap (); 216 Iterator it = defaultEntity.getPrimaryKey().iterator(); 217 while (it.hasNext()) { 218 DbAttribute pk = (DbAttribute) it.next(); 219 id.put(pk.getName(), next.get(pk.getName())); 220 } 221 222 if (fetchedIds.add(id)) { 223 this.nextDataRow = next; 224 break; 225 } 226 } 227 } 228 229 void checkNextId(DbEntity entity) throws CayenneException { 230 if (entity == null) { 231 throw new CayenneException("Null DbEntity, can't create id."); 232 } 233 234 this.readingIds = true; 235 this.nextDataRow = null; 236 237 while (wrappedIterator.hasNextRow()) { 238 Map next = wrappedIterator.nextObjectId(entity); 239 240 if (fetchedIds.add(next)) { 241 this.nextDataRow = next; 242 break; 243 } 244 } 245 } 246 } | Popular Tags |