001 package EVolve; 002 003 /* EVolve - an Extensible Software Visualization Framework 004 * Copyright (C) 2001-2002 Qin Wang 005 * 006 * This library is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Library General Public 008 * License as published by the Free Software Foundation; either 009 * version 2 of the License, or (at your option) any later version. 010 * 011 * This library is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Library General Public License for more details. 015 * 016 * You should have received a copy of the GNU Library General Public 017 * License along with this library; if not, write to the 018 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 019 * Boston, MA 02111-1307, USA. 020 */ 021 022 /* 023 * EVolve is distributed at http://www.sable.mcgill.ca/EVolve/ 024 */ 025 026 import java.io.IOException; 027 import java.io.RandomAccessFile; 028 import java.util.TreeMap; 029 import javax.swing.JFileChooser; 030 import EVolve.data.DataSource; 031 import EVolve.data.ElementDefinition; 032 import EVolve.data.Entity; 033 import EVolve.data.EntityBuilder; 034 import EVolve.data.Event; 035 import EVolve.data.EventBuilder; 036 import EVolve.data.FieldDefinition; 037 import EVolve.data.NumericStringComparator; 038 import EVolve.exceptions.CancelLoadDataException; 039 import EVolve.exceptions.DataProcessingException; 040 import EVolve.exceptions.EVolveException; 041 042 public class DemoSource implements DataSource { 043 private final String dsourceName = "DemoSource"; 044 private String fn = null; // data file name 045 046 private RandomAccessFile file; 047 048 private EntityBuilder classBuilder; 049 050 private EntityBuilder threadBuilder; 051 052 private EntityBuilder methodBuilder; 053 private FieldDefinition methodDefiningClass; 054 055 private EntityBuilder locationBuilder; 056 057 private EntityBuilder sizeBuilder; 058 059 private EventBuilder allocationBuilder; 060 private FieldDefinition allocationObjectCount; 061 private FieldDefinition allocationObjectSize; 062 private FieldDefinition allocationBytecode; 063 private FieldDefinition allocationObjectType; 064 private FieldDefinition allocationThread; 065 private FieldDefinition allocationMethod; 066 private FieldDefinition allocationLocation; 067 private FieldDefinition allocationSize; 068 private FieldDefinition allocationFieldSum; 069 private FieldDefinition allocationFieldCounter; 070 071 private EventBuilder invocationBuilder; 072 private FieldDefinition invocationNumber; 073 private FieldDefinition invocationBytecode; 074 private FieldDefinition invocationThread; 075 private FieldDefinition invocationMethod; 076 private FieldDefinition invocationLocation; 077 private FieldDefinition invocationFieldCounter; 078 079 080 private ElementDefinition[] definition; 081 private int definitionCounter; 082 083 private TreeMap classMap; 084 private TreeMap threadMap; 085 private TreeMap methodMap; 086 private TreeMap locationMap; 087 private TreeMap sizeMap; 088 089 private long counter[]; 090 091 public void init() throws EVolveException { 092 String lastName = fn; 093 094 fn = Scene.getDataFileName(); 095 if (fn == null) { 096 JFileChooser fc = new JFileChooser(Scene.getUIManager().getLastDataDir()); 097 if (fc.showOpenDialog(Scene.getFrame()) == JFileChooser.APPROVE_OPTION) { 098 try { 099 file = new RandomAccessFile(fc.getSelectedFile(), "r"); 100 fn = fc.getSelectedFile().getName(); 101 Scene.setDataFilename(fc.getSelectedFile().getPath()); 102 Scene.getUIManager().setLastDataDir(fc.getSelectedFile().getPath()); 103 Scene.setDataFilename(null); 104 } catch (IOException e) { 105 throw new DataProcessingException("IO exception occurred when access data file."); 106 } 107 } else { 108 fn = lastName; 109 throw new CancelLoadDataException(); 110 } 111 } else { 112 try { 113 file = new RandomAccessFile(fn, "r"); 114 } catch (IOException e) { 115 throw new DataProcessingException("File loading failed."); 116 } 117 } 118 119 } 120 121 public void startBuildDefinition() throws DataProcessingException { 122 String[] propertySum = {"time","sum"}; 123 String[] propertyCount = {"time","count"}; 124 String[] propertyAmount = {"amount"}; 125 String[] propertyCoordinate = {"time","coordinate"}; 126 String[] propertyThread = {"reference","thread"}; 127 128 definition = new ElementDefinition[7]; 129 130 classBuilder = new EntityBuilder("Class", "Class"); 131 definition[0] = classBuilder.buildDefinition(); 132 133 threadBuilder = new EntityBuilder("Thread", "Thread"); 134 definition[1] = threadBuilder.buildDefinition(); 135 136 methodBuilder = new EntityBuilder("Method", "Method"); 137 methodDefiningClass = methodBuilder.buildReferenceDefinition("Defining Class", classBuilder, null, "Defining class of the method"); 138 definition[2] = methodBuilder.buildDefinition(); 139 140 locationBuilder = new EntityBuilder("Location", "Location in Method"); 141 definition[3] = locationBuilder.buildDefinition(); 142 143 sizeBuilder = new EntityBuilder("Size", "Object Size"); 144 sizeBuilder.addComparator(new NumericStringComparator()); 145 definition[4] = sizeBuilder.buildDefinition(); 146 147 allocationBuilder = new EventBuilder("Object Allocation", "Object allocation event"); 148 allocationFieldSum = allocationBuilder.buildValueDefinition("Memory Allocated", propertySum, "Size of memory allocated"); 149 allocationFieldCounter = allocationBuilder.buildValueDefinition("Allocations", propertyCount, "Number of objects allocated"); 150 allocationObjectCount = allocationBuilder.buildValueDefinition("Object Count", propertyAmount, "Number of objects allocated"); 151 allocationObjectSize = allocationBuilder.buildValueDefinition("Memory Allocated", propertyAmount, "Size of memory allocated"); 152 allocationBytecode = allocationBuilder.buildValueDefinition("Bytecode", propertyCoordinate, "Bytecode sequence"); 153 allocationObjectType = allocationBuilder.buildReferenceDefinition("Object Type", classBuilder, null, "Type of the object"); 154 allocationThread = allocationBuilder.buildReferenceDefinition("Thread", threadBuilder, propertyThread, "Thread in which the object is allocated"); 155 allocationMethod = allocationBuilder.buildReferenceDefinition("Allocating Methods", methodBuilder, null, "Method that creates the object"); 156 allocationLocation = allocationBuilder.buildReferenceDefinition("Allocating Locations", locationBuilder, null, "Location where the object is created"); 157 allocationSize = allocationBuilder.buildReferenceDefinition("Allocation Size", sizeBuilder, null, "Allocation Size"); 158 definition[5] = allocationBuilder.buildDefinition(); 159 160 invocationBuilder = new EventBuilder("Method Invocation", "Method invocation event"); 161 invocationFieldCounter = invocationBuilder.buildValueDefinition("Invocations", propertyCount, "Total number of invocations"); 162 invocationNumber = invocationBuilder.buildValueDefinition("Number of Invocations", propertyAmount, "Total number of invocations"); 163 invocationBytecode = invocationBuilder.buildValueDefinition("Bytecode", propertyCoordinate, "Bytecode sequence"); 164 invocationThread = invocationBuilder.buildReferenceDefinition("Thread", threadBuilder, propertyThread, "Thread in which the method is invoked"); 165 invocationMethod = invocationBuilder.buildReferenceDefinition("Method", methodBuilder, null, "Method that is invoked"); 166 invocationLocation = invocationBuilder.buildReferenceDefinition("Invoking Locations", locationBuilder, null, "Location where the method is invoked"); 167 definition[6] = invocationBuilder.buildDefinition(); 168 169 definitionCounter = -1; 170 counter = new long[definition.length]; 171 for (int i=0; i<counter.length; i++) 172 counter[i] = 0; 173 } 174 175 public ElementDefinition getNextDefinition() throws DataProcessingException { 176 definitionCounter++; 177 if (definitionCounter < definition.length) { 178 return definition[definitionCounter]; 179 } else { 180 return null; 181 } 182 } 183 184 private String getSub(String line, int part) { 185 int start = line.indexOf(' ') + 1; 186 int i = 1; 187 while (i < part) { 188 start = line.indexOf(' ', start) + 1; 189 i++; 190 } 191 int end = line.indexOf(' ', start); 192 if (end == -1) { 193 return line.substring(start); 194 } else { 195 return line.substring(start, end); 196 } 197 } 198 199 public void startBuildEntity() throws DataProcessingException { 200 try { 201 file.seek(0); 202 203 classMap = new TreeMap(); 204 threadMap = new TreeMap(); 205 methodMap = new TreeMap(); 206 locationMap = new TreeMap(); 207 sizeMap = new TreeMap(); 208 } catch (IOException e) { 209 throw new DataProcessingException("File processing failed."); 210 } 211 } 212 213 public Entity getNextEntity() throws DataProcessingException { 214 try { 215 Entity returnVal = null; 216 String line = file.readLine(); 217 218 while ((returnVal == null) && (line != null) && (line.length()>0)) { 219 line = line.trim(); 220 char ch = line.charAt(0); 221 222 if (ch == 'C') { 223 classBuilder.newEntity(getSub(line, 1)); 224 returnVal = classBuilder.buildEntity(); 225 classMap.put(getSub(line, 2), returnVal); 226 } else if (ch == 'T') { 227 threadBuilder.newEntity(getSub(line, 1)); 228 returnVal = threadBuilder.buildEntity(); 229 threadMap.put(getSub(line, 2), returnVal); 230 } else if (ch == 'M') { 231 methodBuilder.newEntity(getSub(line, 1)); 232 methodBuilder.addReferenceField(methodDefiningClass, (Entity)(classMap.get(getSub(line, 3)))); 233 returnVal = methodBuilder.buildEntity(); 234 methodMap.put(getSub(line, 2), returnVal); 235 } else if (ch == 'L') { 236 locationBuilder.newEntity(getSub(line, 1)); 237 returnVal = locationBuilder.buildEntity(); 238 locationMap.put(getSub(line, 2), returnVal); 239 } else if (ch == 'O') { 240 String size = getSub(line, 6); 241 if (!sizeMap.containsKey(size)) { 242 sizeBuilder.newEntity(size); 243 returnVal = sizeBuilder.buildEntity(); 244 sizeMap.put(size, returnVal); 245 } 246 counter[5]++; 247 } else if (ch == '+') { 248 counter[6]+=2; 249 } 250 251 if (returnVal == null) { 252 line = file.readLine(); 253 } 254 } 255 256 return returnVal; 257 } catch (IOException e) { 258 throw new DataProcessingException("File processing failed."); 259 } 260 } 261 262 public void startBuildEvent() throws DataProcessingException { 263 try { 264 file.seek(0); 265 } catch (IOException e) { 266 throw new DataProcessingException("File processing failed."); 267 } 268 } 269 270 public Event getNextEvent() throws DataProcessingException { 271 try { 272 Event returnVal = null; 273 String line = file.readLine(); 274 275 while ((returnVal == null) && (line != null)) { 276 line = line.trim(); 277 char ch = line.charAt(0); 278 279 if (ch == 'O') { 280 allocationBuilder.newEvent(); 281 String size = getSub(line, 6); 282 allocationBuilder.addValueField(allocationObjectCount, 1); 283 allocationBuilder.addValueField(allocationObjectSize, Integer.parseInt(getSub(line, 6))); 284 allocationBuilder.addValueField(allocationFieldCounter, 1); 285 allocationBuilder.addValueField(allocationFieldSum, Integer.parseInt(getSub(line, 6))); 286 allocationBuilder.addValueField(allocationBytecode, Integer.parseInt(getSub(line, 1))); 287 allocationBuilder.addReferenceField(allocationObjectType, (Entity)(classMap.get(getSub(line, 5)))); 288 allocationBuilder.addReferenceField(allocationThread, (Entity)(threadMap.get(getSub(line, 2)))); 289 allocationBuilder.addReferenceField(allocationMethod, (Entity)(methodMap.get(getSub(line, 3)))); 290 allocationBuilder.addReferenceField(allocationLocation, (Entity)(locationMap.get(getSub(line, 4)))); 291 allocationBuilder.addReferenceField(allocationSize, (Entity)(sizeMap.get(size))); 292 returnVal = allocationBuilder.buildEvent(); 293 } else if (ch == '+') { 294 invocationBuilder.newEvent(); 295 invocationBuilder.addValueField(invocationNumber, 1); 296 invocationBuilder.addValueField(invocationFieldCounter, 1); 297 invocationBuilder.addValueField(invocationBytecode, Integer.parseInt(getSub(line, 1))); 298 invocationBuilder.addReferenceField(invocationThread, (Entity)(threadMap.get(getSub(line, 2)))); 299 invocationBuilder.addReferenceField(invocationMethod, (Entity)(methodMap.get(getSub(line, 3)))); 300 invocationBuilder.addReferenceField(invocationLocation, (Entity)(locationMap.get(getSub(line, 4)))); 301 returnVal = invocationBuilder.buildEvent(); 302 } else if (ch == '-') { 303 invocationBuilder.newEvent(true); 304 invocationBuilder.addValueField(invocationNumber, 1); 305 invocationBuilder.addValueField(invocationBytecode, Integer.parseInt(getSub(line, 1))); 306 invocationBuilder.addReferenceField(invocationThread, (Entity)(threadMap.get(getSub(line, 2)))); 307 invocationBuilder.addReferenceField(invocationMethod, (Entity)(methodMap.get(getSub(line, 3)))); 308 invocationBuilder.addReferenceField(invocationLocation, (Entity)(locationMap.get(getSub(line, 4)))); 309 returnVal = invocationBuilder.buildEvent(); 310 } 311 312 if (returnVal == null) { 313 line = file.readLine(); 314 } 315 } 316 317 return returnVal; 318 } catch (IOException e) { 319 throw new DataProcessingException("File processing failed."); 320 } 321 } 322 323 public String getName() { 324 return dsourceName; 325 } 326 327 public String getFileName() { 328 return fn; 329 } 330 331 public long getTotalNumberOfEvents() { 332 long total = 0; 333 334 for (int i=0; i<definition.length; i++) 335 total = total + counter[i]; 336 337 return total; 338 } 339 340 public long getNumberOfEvents(String definitionName) { 341 long number = 0; 342 343 for (int i=0; i<definition.length; i++) { 344 if (definition[i].getName().equals(definitionName)) { 345 number = counter[i]; 346 if (definitionName.equals("Method Invocation")) number = number/2; 347 break; 348 } 349 } 350 351 return number; 352 } 353 }