001 /* EVolve - an Extensible Software Visualization Framework 002 * Copyright (C) 2001-2002 Qin Wang 003 * 004 * This library is free software; you can redistribute it and/or 005 * modify it under the terms of the GNU Library General Public 006 * License as published by the Free Software Foundation; either 007 * version 2 of the License, or (at your option) any later version. 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Library General Public License for more details. 013 * 014 * You should have received a copy of the GNU Library General Public 015 * License along with this library; if not, write to the 016 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 017 * Boston, MA 02111-1307, USA. 018 */ 019 020 /* 021 * EVolve is distributed at http://www.sable.mcgill.ca/EVolve/ 022 */ 023 024 package EVolve.visualization; 025 026 import java.util.*; 027 import EVolve.Scene; 028 import EVolve.data.Element; 029 import EVolve.data.Entity; 030 import EVolve.data.EntityComparator; 031 import EVolve.data.EntityDefinition; 032 import EVolve.data.LexicalComparator; 033 import EVolve.data.Selection; 034 import EVolve.data.ValueComparator; 035 import EVolve.exceptions.NoDataPlotException; 036 import EVolve.util.HelperFuncs; 037 import EVolve.util.Sorter; 038 039 public class ReferenceDimension extends Dimension implements Cloneable{ 040 private ArrayList comparatorList; 041 private int currentOrder; 042 private int[] order; 043 private int [] orderBfUnify; 044 private Entity[] entity; 045 private HashSet linkedEntity; 046 private int selectedIndex; 047 private int entityNumber; 048 private HashMap Int2Entity, EntityName2Int; 049 private Sorter sorter; 050 private ArrayList availableSortScheme; 051 private boolean sortable; 052 053 public ReferenceDimension() { 054 comparatorList = new ArrayList(); 055 linkedEntity = null; 056 selectedIndex = 0; 057 entityNumber = -1; 058 Int2Entity = new HashMap(); 059 EntityName2Int = new HashMap(); 060 orderBfUnify = null; 061 availableSortScheme = new ArrayList(); 062 availableSortScheme.add("Lexical"); 063 availableSortScheme.add("Temporal"); 064 sortable = false; 065 } 066 067 public ReferenceDimension(boolean sortable) { 068 this(); 069 this.sortable = sortable; 070 } 071 072 public int getMaxEntityNumber() { 073 return Scene.getDataManager().getEntity()[dataFilter.getTargetType()].size(); 074 } 075 076 public int getEntityNumber() { 077 return entity==null ? -1 : entity.length; 078 } 079 080 public long getField(Element element) { 081 long returnVal = dataFilter.getData(element); 082 Integer mappedId = findMappedId(returnVal); 083 084 if (order[mappedId.intValue()] == Integer.MAX_VALUE) { 085 order[mappedId.intValue()] = currentOrder; 086 currentOrder++; 087 } 088 return mappedId.intValue(); 089 } 090 091 public void preVisualize() { 092 currentOrder = 0; 093 EntityName2Int.clear(); 094 Int2Entity.clear(); 095 order = new int[getMaxEntityNumber()]; 096 for (int i = 0; i < order.length; i++) { 097 order[i] = Integer.MAX_VALUE; 098 } 099 } 100 101 public void restore() { 102 order = new int[getMaxEntityNumber()]; 103 for (int i = 0; i < order.length; i++) { 104 if (i<currentOrder) 105 order[i] = i; 106 else 107 order[i] = Integer.MAX_VALUE; 108 } 109 linkedEntity = null; 110 111 ArrayList tobeDel = new ArrayList(); 112 Iterator it = Int2Entity.keySet().iterator(); 113 while (it.hasNext()) { 114 Integer key = (Integer)it.next(); 115 if (key.intValue() >= currentOrder) { 116 tobeDel.add(key); 117 } 118 } 119 for (int i=0; i<tobeDel.size(); i++) { 120 Int2Entity.remove(tobeDel.get(i)); 121 } 122 123 tobeDel.clear(); 124 it = EntityName2Int.keySet().iterator(); 125 while (it.hasNext()) { 126 Object key = it.next(); 127 Integer value = (Integer)EntityName2Int.get(key); 128 if (value.intValue() >= currentOrder) { 129 tobeDel.add(key); 130 } 131 } 132 for (int i=0; i<tobeDel.size(); i++) { 133 EntityName2Int.remove(tobeDel.get(i)); 134 } 135 } 136 137 public void visualize() throws NoDataPlotException{ 138 139 if (linkedEntity == null) { 140 entity = new Entity[currentOrder]; 141 142 for (int i = 0; i < order.length; i++) { 143 if (order[i] != Integer.MAX_VALUE) { 144 entity[order[i]] = (Entity)Int2Entity.get(new Integer(i)); 145 } 146 } 147 } else { // unified reference dimension 148 int free = currentOrder; 149 entityNumber = currentOrder; 150 entity = new Entity[linkedEntity.size()]; 151 152 order = new int[linkedEntity.size()]; 153 Iterator it = linkedEntity.iterator(); 154 while (it.hasNext()) { 155 Entity aEntity = (Entity)it.next(); 156 Integer mappedId = (Integer)EntityName2Int.get(aEntity.getName()); 157 if (mappedId != null) { 158 order[mappedId.intValue()] = mappedId.intValue(); 159 entity[order[mappedId.intValue()]] = aEntity; 160 } else { 161 Int2Entity.put(new Integer(free), aEntity); 162 EntityName2Int.put(aEntity.getName(), new Integer(free)); 163 order[free] = Integer.MAX_VALUE; 164 entity[free] = aEntity; 165 free++; 166 } 167 } 168 } 169 170 comparatorList.clear(); 171 comparatorList.add(new LexicalComparator()); 172 comparatorList.add(new ValueComparator("Temporal", true, order, EntityName2Int)); 173 ArrayList entityComparatorList = ((EntityDefinition)(Scene.getDataManager().getElementDefinition()[dataFilter.getTargetType()])).getComparator(); 174 for (int i = 0; i < entityComparatorList.size(); i++) { 175 comparatorList.add(entityComparatorList.get(i)); 176 } 177 178 if (selectedIndex < comparatorList.size()) 179 sorter = new Sorter(entity, (EntityComparator)(comparatorList.get(selectedIndex))); 180 181 // we generate an exception on purpose for empty image 182 if (entity.length == 0) throw new NoDataPlotException(); 183 } 184 185 public Entity getEntity(int index) { 186 int newMappedId = (sorter == null) ? index : sorter.getSource(index); 187 188 if ((newMappedId < currentOrder)&&(Int2Entity.containsKey(new Integer(newMappedId)))) { 189 return (Entity)Int2Entity.get(new Integer(newMappedId)); 190 } 191 192 return null; 193 } 194 195 public ArrayList getComparator() { 196 return comparatorList; 197 } 198 199 public void selectComparator(int selectedIndex) { 200 sorter = new Sorter(entity, (EntityComparator)(comparatorList.get(selectedIndex))); 201 this.selectedIndex = selectedIndex; 202 } 203 204 public void selectComparator(String comparatorName) { 205 for (int i=0; i<comparatorList.size(); i++) { 206 if (comparatorName.equals(((EntityComparator)comparatorList.get(i)).getName())) { 207 selectComparator(i); 208 } 209 } 210 } 211 212 public void addComparator(EntityComparator comparator) { 213 boolean found = false; 214 for (int i=0; i<comparatorList.size(); i++) { 215 if (((EntityComparator)comparatorList.get(i)).getName().equals(comparator.getName())) 216 found = true; 217 } 218 if (!found) comparatorList.add(comparator); 219 } 220 221 public int getSortedIndex(int mappedId) { 222 if (order[mappedId] == Integer.MAX_VALUE) { 223 return -1; 224 } else { 225 return sorter.getTarget(order[mappedId]); 226 } 227 } 228 229 public int getOriginMappedId(int sortedId) { 230 int mappedId = sorter.getSource(sortedId); 231 return mappedId; 232 } 233 234 public void makeSelection(String name, int sourceType, int[] selection) { 235 if (selection.length != 0) { 236 ArrayList temp = new ArrayList(); 237 for (int i = 0; i < selection.length; i++) { 238 Entity aEntity = getEntity(selection[i]); 239 if (aEntity!=null) temp.add(aEntity); 240 } 241 242 long[] selected = new long[temp.size()]; 243 for (int i = 0; i < temp.size(); i++) { 244 selected[i] = ((Entity)temp.get(i)).getId(); 245 } 246 Scene.getFilter().addSelection(new Selection(name,sourceType,dataFilter.getTargetType(),dataFilter.getName(), 247 selected, 0, Long.MAX_VALUE,null)); 248 } 249 } 250 251 public void makeSelection(String name, int sourceType, int[] selection, long start, long end, ArrayList timeMap) { 252 if (selection.length != 0) { 253 ArrayList temp = new ArrayList(); 254 for (int i = 0; i < selection.length; i++) { 255 Entity aEntity = getEntity(selection[i]); 256 if (aEntity!=null) temp.add(aEntity); 257 } 258 259 long[] selected = new long[temp.size()]; 260 for (int i = 0; i < temp.size(); i++) { 261 selected[i] = ((Entity)temp.get(i)).getId(); 262 } 263 Scene.getFilter().addSelection(new Selection(name, sourceType, dataFilter.getTargetType(), 264 dataFilter.getName(),selected, start, end, timeMap)); 265 } 266 } 267 268 public Entity[] getEntities() { 269 return entity; 270 } 271 272 public void linkEntities(HashSet linkedEntity) { 273 if (this.linkedEntity != null) 274 restore(); 275 this.linkedEntity = linkedEntity; 276 } 277 278 public void clearEntityMap() { 279 linkedEntity = null; 280 entity = null; 281 entityNumber = -1; 282 } 283 284 public int getSelectedComparatorIndex() { 285 return selectedIndex; 286 } 287 288 public String getSelectedComparatorName() { 289 if (comparatorList.size() == 0) { 290 return new LexicalComparator().getName(); 291 } 292 return ((EntityComparator)comparatorList.get(selectedIndex)).getName(); 293 } 294 295 public int[] getOrdering() { 296 if (orderBfUnify == null) 297 return order; 298 else 299 return orderBfUnify; 300 } 301 302 public void updateOrdering(int[] newOrder) { 303 if (orderBfUnify == null) 304 orderBfUnify = order; 305 order = newOrder; 306 } 307 308 public int getEntityNumberBeforeLink() { 309 return entityNumber; 310 } 311 312 public HashMap getEntityName2IntMap() { 313 return EntityName2Int; 314 } 315 316 public HashMap getInt2EntityMap() { 317 return Int2Entity; 318 } 319 320 public Entity getEntityFromInt(int mappedId) { 321 Integer key = new Integer(mappedId); 322 if (Int2Entity.containsKey(key)) { 323 return (Entity)Int2Entity.get(key); 324 } else 325 return null; 326 } 327 328 private Integer findMappedId(long entityId) { 329 Long value = new Long(entityId); 330 Entity entity = (Entity)Scene.getDataManager().getEntity()[dataFilter.getTargetType()].get(value); 331 332 if (EntityName2Int.containsKey(entity.getName())) { 333 return (Integer)EntityName2Int.get(entity.getName()); 334 } else { 335 Integer mappedId = new Integer(Int2Entity.size()); 336 Int2Entity.put(mappedId,entity); 337 EntityName2Int.put(entity.getName(),mappedId); 338 return mappedId; 339 } 340 } 341 342 public ArrayList getAvailableSortSchemes() { 343 344 ArrayList entityComparatorList = ((EntityDefinition)(Scene.getDataManager().getElementDefinition()[dataFilter.getTargetType()])).getComparator(); 345 346 ArrayList returnVal = new ArrayList(); 347 for (int i=0; i<availableSortScheme.size(); i++) { 348 returnVal.add(availableSortScheme.get(i)); 349 } 350 for (int i = 0; i < entityComparatorList.size(); i++) { 351 String newScheme = ((EntityComparator)entityComparatorList.get(i)).getName(); 352 if (!availableSortScheme.contains(newScheme)) 353 returnVal.add(newScheme); 354 } 355 356 return returnVal; 357 } 358 359 public void addSortSchemes(String newScheme) { 360 if (!availableSortScheme.contains(newScheme)) 361 availableSortScheme.add(newScheme); 362 } 363 364 public boolean isSortable() { 365 return sortable; 366 } 367 368 public Object clone() { 369 ReferenceDimension o = (ReferenceDimension) super.clone(); 370 o.comparatorList = (ArrayList)comparatorList.clone(); 371 o.comparatorList.clear(); 372 for (int i=0; i<comparatorList.size(); i++) { 373 o.comparatorList.add(((EntityComparator)comparatorList.get(i)).clone()); 374 } 375 o.entity = null; 376 if (entity != null) { 377 o.entity = new Entity[entity.length]; 378 for (int i=0; i<o.entity.length; i++) 379 o.entity[i] = entity[i]; 380 } 381 o.linkedEntity = HelperFuncs.cloneHashSet(linkedEntity); 382 o.Int2Entity = HelperFuncs.cloneHashMap(Int2Entity); 383 o.EntityName2Int = HelperFuncs.cloneHashMap(EntityName2Int); 384 385 o.order = null; 386 if (order != null) { 387 o.order = new int[order.length]; 388 for (int i=0; i<order.length; i++) { 389 o.order[i] = order[i]; 390 } 391 } 392 393 o.sorter = (sorter == null) ? null : (Sorter)sorter.clone(); 394 o.sortable = sortable; 395 return o; 396 } 397 }